# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.1305.9.1+1.1063.9.79 -> 1.1305.9.2
# arch/i386/kernel/process.c 1.49.1.1 -> 1.52
# arch/ppc64/kernel/signal.c 1.27.1.1 -> 1.29
# arch/sparc/kernel/module.c 1.10.1.1 -> 1.12
# arch/alpha/kernel/module.c 1.4.1.1 -> 1.6
# include/asm-ppc64/unistd.h 1.20.1.1 -> 1.23
# kernel/ksyms.c 1.203 -> 1.204
# fs/select.c 1.19.1.1 -> 1.21
# include/linux/timex.h 1.5.1.1 -> 1.9
# include/linux/mm.h 1.121 -> 1.122
# arch/arm/kernel/module.c 1.6.1.1 -> 1.8
# drivers/serial/8250.c 1.33 -> 1.34
# drivers/serial/8250_hcdp.c 1.1 -> (deleted)
# include/asm-ppc64/processor.h 1.29.1.1 -> 1.31
# drivers/char/drm/i830_dma.c 1.18.1.1 -> 1.20
# include/linux/sched.h 1.151 -> 1.152
# include/asm-ppc64/module.h 1.3.1.1 -> 1.5
# kernel/fork.c 1.123 -> 1.123.1.1
# kernel/sys.c 1.43.1.4 -> 1.45
# kernel/sysctl.c 1.45 -> 1.45.1.1
# include/asm-ppc64/thread_info.h 1.7.1.1 -> 1.9
# arch/ppc64/kernel/chrp_setup.c 1.27.1.1 -> 1.30
# include/asm-i386/thread_info.h 1.11.1.1 -> 1.13
# drivers/char/drm/r128_cce.c 1.12.1.1 -> 1.14
# drivers/char/drm/drm_memory_debug.h 1.1.1.1 -> 1.3
# arch/i386/kernel/traps.c 1.51.1.2 -> 1.53
# drivers/char/drm/drm_memory.h 1.8.1.3 -> 1.10
# drivers/char/drm/radeon_cp.c 1.20 -> 1.21
# include/linux/serial.h 1.8.1.1 -> 1.10
# include/asm-ppc/pgtable.h 1.23 -> 1.24
# include/asm-ppc/thread_info.h 1.7.1.1 -> 1.9
# kernel/time.c 1.11.1.1 -> 1.15
# drivers/char/drm/drm_bufs.h 1.14.1.1 -> 1.16
# kernel/softirq.c 1.39.1.2 -> 1.41
# drivers/acpi/pci_root.c 1.13.1.1 -> 1.15
# arch/ppc/kernel/module.c 1.9 -> 1.10
# arch/ppc64/kernel/ras.c 1.4.1.1 -> 1.6
# include/asm-parisc/thread_info.h 1.2.1.1 -> 1.4
# include/asm-um/thread_info.h 1.3.1.1 -> 1.5
# include/asm-h8300/thread_info.h 1.1.1.1 -> 1.3
# drivers/char/drm/i810_dma.c 1.26.1.1 -> 1.28
# drivers/serial/8250_hcdp.h 1.1 -> (deleted)
# include/asm-v850/thread_info.h 1.2.1.1 -> 1.4
# include/linux/pci_ids.h 1.103 -> 1.104
# include/linux/irq.h 1.6.1.1 -> 1.8
# include/linux/moduleloader.h 1.5.1.1 -> 1.7
# include/asm-alpha/unistd.h 1.18.1.2 -> 1.20
# include/asm-m68knommu/thread_info.h 1.2.1.1 -> 1.4
# arch/ppc64/kernel/irq.c 1.25.1.1 -> 1.30
# drivers/acpi/pci_irq.c 1.16.1.2 -> 1.18
# mm/memory.c 1.123.1.2 -> 1.128
# arch/ppc64/kernel/setup.c 1.24.2.1 -> 1.29
# include/asm-arm/thread_info.h 1.6.1.1 -> 1.8
# arch/i386/kernel/module.c 1.10.1.1 -> 1.12
# drivers/serial/Makefile 1.14.1.2 -> 1.16
# include/linux/acpi_serial.h 1.2.1.1 -> 1.4
# drivers/char/mem.c 1.42 -> 1.43
# arch/ppc64/kernel/traps.c 1.16.2.1 -> 1.20
# arch/ppc64/kernel/head.S 1.31.1.1 -> 1.37
# kernel/posix-timers.c 1.17 -> 1.17.1.1
# include/linux/sunrpc/svc.h 1.19.1.1 -> 1.21
# arch/ppc64/kernel/xics.c 1.22.2.1 -> 1.25
# include/linux/sysctl.h 1.47 -> 1.48
# drivers/net/tg3.c 1.72 -> 1.73
# include/linux/smp.h 1.22.1.3 -> 1.24
# arch/v850/kernel/module.c 1.4.1.1 -> 1.6
# arch/ppc64/mm/init.c 1.42.1.1 -> 1.47
# arch/ppc64/kernel/htab.c 1.33.1.1 -> 1.35
# drivers/char/agp/i460-agp.c 1.25 -> 1.26
# arch/ppc64/kernel/process.c 1.31.1.1 -> 1.36
# arch/ppc64/kernel/pci_dma.c 1.14.1.1 -> 1.17
# fs/proc/base.c 1.45 -> 1.46
# mm/mmap.c 1.85 -> 1.86
# include/linux/time.h 1.13.1.1 -> 1.14.1.1
# arch/sparc64/kernel/module.c 1.12.1.1 -> 1.15
# include/asm-i386/unistd.h 1.24.1.1 -> 1.26
# sound/oss/cs4281/cs4281pm-24.c 1.3.1.1 -> 1.5
# arch/ppc64/kernel/asm-offsets.c 1.13.1.1 -> 1.15
# include/asm-m68k/thread_info.h 1.4.1.1 -> 1.6
# Makefile 1.410 -> 1.411
# fs/fcntl.c 1.25.1.3 -> 1.29
# include/asm-s390/thread_info.h 1.4.1.1 -> 1.6
# arch/ppc64/mm/numa.c 1.4.1.1 -> 1.8
# arch/ppc64/kernel/syscalls.c 1.10.1.1 -> 1.12
# drivers/char/agp/backend.c 1.83 -> 1.84
# include/asm-x86_64/thread_info.h 1.12 -> 1.13
# arch/ppc64/kernel/sys_ppc32.c 1.63 -> 1.63.1.1
# include/asm-sparc64/thread_info.h 1.10.1.1 -> 1.12
# arch/ppc64/kernel/prom.c 1.25.2.1 -> 1.29
# include/asm-x86_64/pgtable.h 1.20 -> 1.20.1.1
# kernel/module.c 1.86 -> 1.87
# arch/ppc64/kernel/iSeries_setup.c 1.12.1.1 -> 1.16
# arch/ppc64/kernel/smp.c 1.34.2.1 -> 1.39
# drivers/char/drm/drmP.h 1.23.1.2 -> 1.25
# include/asm-i386/pgtable.h 1.35.1.1 -> 1.37
# net/ipv4/tcp_input.c 1.39 -> 1.40
# include/linux/highmem.h 1.25.1.1 -> 1.27
# arch/ppc64/kernel/pacaData.c 1.6.1.1 -> 1.8
# kernel/sched.c 1.192 -> 1.192.1.1
# drivers/char/agp/hp-agp.c 1.24 -> 1.25
# drivers/acpi/osl.c 1.37 -> 1.38
# arch/alpha/kernel/traps.c 1.24.1.1 -> 1.26
# drivers/char/drm/drm_drv.h 1.20 -> 1.21
# kernel/timer.c 1.57 -> 1.57.1.1
# arch/ppc64/kernel/pci.c 1.30.1.1 -> 1.34
# include/asm-m68k/pgtable.h 1.8 -> 1.9
# arch/ppc64/kernel/misc.S 1.57.1.1 -> 1.61
# drivers/char/drm/mga_dma.c 1.13.1.1 -> 1.15
# arch/s390/kernel/module.c 1.7.1.1 -> 1.9
# drivers/char/drm/mga_drv.h 1.13.1.1 -> 1.15
# arch/x86_64/kernel/module.c 1.7.1.1 -> 1.10
# include/linux/percpu.h 1.5.1.2 -> 1.7
# arch/arm/kernel/process.c 1.28.1.1 -> 1.30
# arch/ppc64/kernel/signal32.c 1.39.1.1 -> 1.41
# include/asm-alpha/thread_info.h 1.5.1.1 -> 1.7
# drivers/serial/Kconfig 1.8.1.1 -> 1.10
# drivers/char/drm/gamma_dma.c 1.12.1.2 -> 1.14
# include/linux/irq_cpustat.h 1.7.1.1 -> 1.9
# include/asm-ppc64/pgtable.h 1.23 -> 1.24
# include/asm-ppc64/mmzone.h 1.10.1.1 -> 1.12
# include/asm-sparc/thread_info.h 1.4.1.1 -> 1.6
# drivers/video/radeonfb.c 1.26.1.3 -> 1.28
# include/asm-ppc64/topology.h 1.7.1.1 -> 1.9
# arch/ppc64/kernel/module.c 1.4.1.1 -> 1.7
# arch/ppc64/kernel/Makefile 1.23.1.1 -> 1.28
# sound/oss/cs4281/cs4281m.c 1.21.1.3 -> 1.23
# arch/ppc64/kernel/align.c 1.8.1.1 -> 1.11
# arch/ppc64/kernel/ioctl32.c 1.30.1.1 -> 1.36
# drivers/scsi/qla1280.c 1.38 -> 1.39
# drivers/char/drm/drm_vm.h 1.23.1.1 -> 1.25
# arch/parisc/kernel/module.c 1.3.1.1 -> 1.4.1.1
# drivers/scsi/sym53c8xx_2/sym_glue.c 1.23 -> 1.24
#
diff -Nru a/Makefile b/Makefile
--- a/Makefile Thu Jun 19 00:45:34 2003
+++ b/Makefile Thu Jun 19 00:45:34 2003
@@ -213,7 +213,7 @@
NOSTDINC_FLAGS = -nostdinc -iwithprefix include
CPPFLAGS := -D__KERNEL__ -Iinclude
-CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
+CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -g -O2 \
-fno-strict-aliasing -fno-common
AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS)
diff -Nru a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
--- a/arch/alpha/kernel/traps.c Thu Jun 19 00:45:34 2003
+++ b/arch/alpha/kernel/traps.c Thu Jun 19 00:45:34 2003
@@ -148,7 +148,7 @@
static int kstack_depth_to_print = 24;
-void show_stack(unsigned long *sp)
+void show_stack(struct task_struct *task, unsigned long *sp)
{
unsigned long *stack;
int i;
@@ -174,7 +174,7 @@
void dump_stack(void)
{
- show_stack(NULL);
+ show_stack(NULL, NULL);
}
void
diff -Nru a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
--- a/arch/i386/kernel/process.c Thu Jun 19 00:45:34 2003
+++ b/arch/i386/kernel/process.c Thu Jun 19 00:45:34 2003
@@ -212,7 +212,6 @@
*/
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
- struct task_struct *p;
struct pt_regs regs;
memset(®s, 0, sizeof(regs));
@@ -228,8 +227,7 @@
regs.eflags = 0x286;
/* Ok, create the new process.. */
- p = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
- return IS_ERR(p) ? PTR_ERR(p) : p->pid;
+ return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
}
/*
@@ -518,27 +516,22 @@
asmlinkage int sys_fork(struct pt_regs regs)
{
- struct task_struct *p;
-
- p = do_fork(SIGCHLD, regs.esp, ®s, 0, NULL, NULL);
- return IS_ERR(p) ? PTR_ERR(p) : p->pid;
+ return do_fork(SIGCHLD, regs.esp, ®s, 0, NULL, NULL);
}
asmlinkage int sys_clone(struct pt_regs regs)
{
- struct task_struct *p;
unsigned long clone_flags;
unsigned long newsp;
- int *parent_tidptr, *child_tidptr;
+ int __user *parent_tidptr, *child_tidptr;
clone_flags = regs.ebx;
newsp = regs.ecx;
- parent_tidptr = (int *)regs.edx;
- child_tidptr = (int *)regs.edi;
+ parent_tidptr = (int __user *)regs.edx;
+ child_tidptr = (int __user *)regs.edi;
if (!newsp)
newsp = regs.esp;
- p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, ®s, 0, parent_tidptr, child_tidptr);
- return IS_ERR(p) ? PTR_ERR(p) : p->pid;
+ return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, ®s, 0, parent_tidptr, child_tidptr);
}
/*
@@ -553,10 +546,7 @@
*/
asmlinkage int sys_vfork(struct pt_regs regs)
{
- struct task_struct *p;
-
- p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, ®s, 0, NULL, NULL);
- return IS_ERR(p) ? PTR_ERR(p) : p->pid;
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, ®s, 0, NULL, NULL);
}
/*
diff -Nru a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
--- a/arch/i386/kernel/traps.c Thu Jun 19 00:45:34 2003
+++ b/arch/i386/kernel/traps.c Thu Jun 19 00:45:34 2003
@@ -101,7 +101,7 @@
stack = (unsigned long*)&stack;
printk("Call Trace:");
-#if CONFIG_KALLSYMS
+#ifdef CONFIG_KALLSYMS
printk("\n");
#endif
i = 1;
@@ -438,7 +438,7 @@
unsigned char reason = get_nmi_reason();
if (!(reason & 0xc0)) {
-#if CONFIG_X86_LOCAL_APIC
+#ifdef CONFIG_X86_LOCAL_APIC
/*
* Ok, so this is none of the documented NMI sources,
* so it must be the NMI watchdog.
diff -Nru a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
--- a/arch/ppc64/kernel/Makefile Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/Makefile Thu Jun 19 00:45:34 2003
@@ -7,9 +7,9 @@
obj-y := setup.o entry.o traps.o irq.o idle.o \
time.o process.o signal.o syscalls.o misc.o ptrace.o \
align.o semaphore.o bitops.o stab.o htab.o pacaData.o \
- udbg.o binfmt_elf32.o sys_ppc32.o sys32.o ioctl32.o \
+ udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \
ptrace32.o signal32.o pmc.o rtc.o init_task.o \
- lmb.o pci.o pci_dn.o pci_dma.o
+ lmb.o pci.o pci_dn.o pci_dma.o cputable.o
obj-$(CONFIG_PPC_ISERIES) += iSeries_pci.o iSeries_pci_reset.o \
iSeries_IoMmTable.o iSeries_irq.o \
@@ -19,14 +19,16 @@
mf.o HvLpEvent.o iSeries_proc.o
obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \
- eeh.o rtasd.o nvram.o
+ eeh.o rtasd.o nvram.o ras.o
# Change this to pSeries only once we've got iSeries up to date
obj-y += open_pic.o xics.o pSeries_htab.o rtas.o \
- chrp_setup.o i8259.o ras.o prom.o
+ chrp_setup.o i8259.o prom.o
obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o
obj-$(CONFIG_PPC_RTAS) += rtas-proc.o
obj-$(CONFIG_SCANLOG) += scanlog.o
+
+CFLAGS_ioctl32.o += -Ifs/
diff -Nru a/arch/ppc64/kernel/align.c b/arch/ppc64/kernel/align.c
--- a/arch/ppc64/kernel/align.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/align.c Thu Jun 19 00:45:34 2003
@@ -20,6 +20,9 @@
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/cache.h>
+#include <asm/cputable.h>
+
+void disable_kernel_fp(void); /* asm function from head.S */
struct aligninfo {
unsigned char len;
@@ -236,12 +239,11 @@
dsisr = regs->dsisr;
- /* Power4 doesn't set DSISR for an alignment interrupt */
- if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) {
- unsigned int real_instr;
- if (__get_user(real_instr, (unsigned int *)regs->nip))
- return 0;
- dsisr = make_dsisr(real_instr);
+ if (cur_cpu_spec->cpu_features & CPU_FTR_NODSISRALIGN) {
+ unsigned int real_instr;
+ if (__get_user(real_instr, (unsigned int *)regs->nip))
+ return 0;
+ dsisr = make_dsisr(*((unsigned *)regs->nip));
}
/* extract the operation and registers from the dsisr */
@@ -309,6 +311,7 @@
/* Doing stfs, have to convert to single */
enable_kernel_fp();
cvt_df(¤t->thread.fpr[reg], (float *)&data.v[4], ¤t->thread.fpscr);
+ disable_kernel_fp();
}
else
data.dd = current->thread.fpr[reg];
@@ -342,6 +345,7 @@
/* Doing lfs, have to convert to double */
enable_kernel_fp();
cvt_fd((float *)&data.v[4], ¤t->thread.fpr[reg], ¤t->thread.fpscr);
+ disable_kernel_fp();
}
else
current->thread.fpr[reg] = data.dd;
diff -Nru a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c
--- a/arch/ppc64/kernel/asm-offsets.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/asm-offsets.c Thu Jun 19 00:45:34 2003
@@ -34,6 +34,7 @@
#include <asm/iSeries/HvLpEvent.h>
#include <asm/prom.h>
#include <asm/rtas.h>
+#include <asm/cputable.h>
#define DEFINE(sym, val) \
asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -158,6 +159,13 @@
DEFINE(CLONE_VM, CLONE_VM);
DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
+
+ /* About the CPU features table */
+ DEFINE(CPU_SPEC_ENTRY_SIZE, sizeof(struct cpu_spec));
+ DEFINE(CPU_SPEC_PVR_MASK, offsetof(struct cpu_spec, pvr_mask));
+ DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value));
+ DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
+ DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
return 0;
}
diff -Nru a/arch/ppc64/kernel/chrp_setup.c b/arch/ppc64/kernel/chrp_setup.c
--- a/arch/ppc64/kernel/chrp_setup.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/chrp_setup.c Thu Jun 19 00:45:34 2003
@@ -62,13 +62,13 @@
#include "open_pic.h"
#include <asm/xics.h>
#include <asm/ppcdebug.h>
+#include <asm/cputable.h>
extern volatile unsigned char *chrp_int_ack_special;
void chrp_progress(char *, unsigned short);
extern void openpic_init_IRQ(void);
-extern void init_ras_IRQ(void);
extern void find_and_init_phbs(void);
@@ -238,7 +238,6 @@
ppc_md.init_IRQ = xics_init_IRQ;
ppc_md.get_irq = xics_get_irq;
}
- ppc_md.init_ras_IRQ = init_ras_IRQ;
ppc_md.init = chrp_init2;
@@ -253,6 +252,34 @@
ppc_md.progress = chrp_progress;
+ /* build up the firmware_features bitmask field
+ * using contents of device-tree/ibm,hypertas-functions.
+ * Ultimately this functionality may be moved into prom.c prom_init().
+ */
+ struct device_node * dn;
+ char * hypertas;
+ unsigned int len;
+ dn = find_path_device("/rtas");
+ cur_cpu_spec->firmware_features = 0;
+ hypertas = get_property(dn, "ibm,hypertas-functions", &len);
+ if (hypertas) {
+ while (len > 0){
+ int i;
+ /* check value against table of strings */
+ for(i=0; i < FIRMWARE_MAX_FEATURES ;i++) {
+ if ((firmware_features_table[i].name) && (strcmp(firmware_features_table[i].name,hypertas))==0) {
+ /* we have a match */
+ cur_cpu_spec->firmware_features |= (1UL << firmware_features_table[i].val);
+ break;
+ }
+ }
+ int hypertas_len = strlen(hypertas);
+ len -= hypertas_len +1;
+ hypertas+= hypertas_len +1;
+ }
+ }
+ udbg_printf("firmware_features bitmask: 0x%x \n",
+ cur_cpu_spec->firmware_features);
}
void
diff -Nru a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
--- a/arch/ppc64/kernel/head.S Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/head.S Thu Jun 19 00:45:34 2003
@@ -32,6 +32,7 @@
#include <asm/ppc_asm.h>
#include <asm/offsets.h>
#include <asm/bug.h>
+#include <asm/cputable.h>
#ifdef CONFIG_PPC_ISERIES
#define DO_SOFT_DISABLE
@@ -582,7 +583,7 @@
cmpi 0,r22,0xc
/* Segment fault on a bolted segment. Go off and map that segment. */
- beq .do_stab_bolted
+ beq- .do_stab_bolted
stab_bolted_user_return:
EXCEPTION_PROLOG_COMMON
ld r3,_DSISR(r1)
@@ -592,7 +593,7 @@
rlwinm r4,r3,32-23,29,29 /* DSISR_STORE -> _PAGE_RW */
ld r3,_DAR(r1) /* into the hash table */
- beq 2f /* If so handle it */
+ beq+ 2f /* If so handle it */
li r4,0x300 /* Trap number */
bl .do_stab_SI
b 1f
@@ -644,7 +645,7 @@
EXCEPTION_PROLOG_COMMON
andis. r0,r23,0x0020 /* no ste found? */
- beq 2f
+ beq+ 2f
mr r3,r22 /* SRR0 at interrupt */
li r4,0x400 /* Trap number */
bl .do_stab_SI
@@ -674,7 +675,7 @@
li r4,0x480 /* Exception vector */
bl .ste_allocate
or. r3,r3,r3 /* Check return code */
- beq fast_exception_return /* Return if we succeeded */
+ beq+ fast_exception_return /* Return if we succeeded */
addi r3,r1,STACK_FRAME_OVERHEAD
#ifdef DO_SOFT_DISABLE
@@ -878,18 +879,8 @@
mfspr r22,DSISR
andis. r22,r22,0x0020
- bne+ 2f
- ld r22,8(r21) /* get SRR1 */
- andi. r22,r22,MSR_PR /* check if from user */
- bne+ stab_bolted_user_return /* from user, send the error on up */
-#if 0
- li r3,0
-#ifdef CONFIG_XMON
- bl .xmon
-#endif
-1: b 1b
-#endif
-2:
+ beq- stab_bolted_user_return
+
/* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */
mfspr r21,DAR
rldicl r20,r21,36,32 /* Permits a full 32b of ESID */
@@ -1079,9 +1070,11 @@
oris r21,r23,2048 /* valid bit */
rldimi r21,r22,0,52 /* Insert entry */
- isync
+ /*
+ * No need for an isync before or after this slbmte. The exception
+ * we enter with and the rfid we exit with are context synchronizing .
+ */
slbmte r20,r21
- isync
/* All done -- return from exception. */
mfsprg r20,3 /* Load the PACA pointer */
@@ -1248,6 +1241,11 @@
li r0,0
stdu r0,-STACK_FRAME_OVERHEAD(r1)
+ LOADADDR(r3,cpu_specs)
+ LOADADDR(r4,cur_cpu_spec)
+ li r5,0
+ bl .identify_cpu
+
LOADADDR(r2,__toc_start)
addi r2,r2,0x4000
addi r2,r2,0x4000
@@ -1691,6 +1689,13 @@
li r0,0
stdu r0,-STACK_FRAME_OVERHEAD(r1)
+ LOADADDR(r3,cpu_specs)
+ sub r3,r3,r26
+ LOADADDR(r4,cur_cpu_spec)
+ sub r4,r4,r26
+ mr r5,r26
+ bl .identify_cpu
+
/* set up the TOC (physical address) */
LOADADDR(r2,__toc_start)
addi r2,r2,0x4000
@@ -1814,9 +1819,9 @@
li r5,0
std r0,PACAKSAVE(r13)
- /* ptr to hardware interrupt stack for processor 0 */
+ /* ptr to hardware interrupt stack for boot processor */
LOADADDR(r3, hardware_int_paca0)
- li r5,0x1000
+ li r5,PAGE_SIZE
sldi r5,r5,3
subi r5,r5,STACK_FRAME_OVERHEAD
@@ -1849,6 +1854,11 @@
bl .start_kernel
+_GLOBAL(__setup_cpu_power3)
+ blr
+_GLOBAL(__setup_cpu_power4)
+ blr
+
_GLOBAL(hmt_init)
#ifdef CONFIG_HMT
LOADADDR(r5, hmt_thread_data)
@@ -1944,7 +1954,7 @@
.globl hardware_int_paca0
hardware_int_paca0:
- .space 8*4096
+ .space 8*PAGE_SIZE
/* 1 page segment table per cpu (max 48) */
.globl stab_array
diff -Nru a/arch/ppc64/kernel/htab.c b/arch/ppc64/kernel/htab.c
--- a/arch/ppc64/kernel/htab.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/htab.c Thu Jun 19 00:45:34 2003
@@ -46,6 +46,7 @@
#include <asm/eeh.h>
#include <asm/tlb.h>
#include <asm/cacheflush.h>
+#include <asm/cputable.h>
/*
* Note: pte --> Linux PTE
@@ -101,7 +102,7 @@
hpteg = ((hash & htab_data.htab_hash_mask)*HPTES_PER_GROUP);
- if (naca->platform == PLATFORM_PSERIES_LPAR)
+ if (systemcfg->platform == PLATFORM_PSERIES_LPAR)
ret = pSeries_lpar_hpte_insert(hpteg, va,
(unsigned long)__v2a(addr) >> PAGE_SHIFT,
0, mode, 1, large);
@@ -140,7 +141,7 @@
htab_data.htab_num_ptegs = pteg_count;
htab_data.htab_hash_mask = pteg_count - 1;
- if (naca->platform == PLATFORM_PSERIES) {
+ if (systemcfg->platform == PLATFORM_PSERIES) {
/* Find storage for the HPT. Must be contiguous in
* the absolute address space.
*/
@@ -165,15 +166,16 @@
mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX;
/* XXX we currently map kernel text rw, should fix this */
- if (cpu_has_largepage() && naca->physicalMemorySize > 256*MB) {
+ if ((cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE)
+ && systemcfg->physicalMemorySize > 256*MB) {
create_pte_mapping((unsigned long)KERNELBASE,
KERNELBASE + 256*MB, mode_rw, 0);
create_pte_mapping((unsigned long)KERNELBASE + 256*MB,
- KERNELBASE + (naca->physicalMemorySize),
+ KERNELBASE + (systemcfg->physicalMemorySize),
mode_rw, 1);
} else {
create_pte_mapping((unsigned long)KERNELBASE,
- KERNELBASE+(naca->physicalMemorySize),
+ KERNELBASE+(systemcfg->physicalMemorySize),
mode_rw, 0);
}
}
@@ -279,7 +281,8 @@
#define PPC64_HWNOEXEC (1 << 2)
/* We do lazy icache flushing on cpus that support it */
- if (unlikely(cpu_has_noexecute() && pfn_valid(pte_pfn(new_pte)))) {
+ if (unlikely((cur_cpu_spec->cpu_features & CPU_FTR_NOEXECUTE)
+ && pfn_valid(pte_pfn(new_pte)))) {
struct page *page = pte_page(new_pte);
/* page is dirty */
diff -Nru a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
--- a/arch/ppc64/kernel/iSeries_setup.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/iSeries_setup.c Thu Jun 19 00:45:34 2003
@@ -33,6 +33,7 @@
#include <asm/mmu.h>
#include <asm/pgtable.h>
#include <asm/mmu_context.h>
+#include <asm/cputable.h>
#include <asm/time.h>
#include "iSeries_setup.h"
@@ -254,7 +255,7 @@
{
unsigned long i;
unsigned long mem_blocks = 0;
- if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
+ if (cur_cpu_spec->cpu_features & CPU_FTR_SLB)
mem_blocks = iSeries_process_Regatta_mainstore_vpd( mb_array, max_entries );
else
mem_blocks = iSeries_process_Condor_mainstore_vpd( mb_array, max_entries );
@@ -311,7 +312,6 @@
ppc_md.setup_residual = iSeries_setup_residual;
ppc_md.get_cpuinfo = iSeries_get_cpuinfo;
ppc_md.init_IRQ = iSeries_init_IRQ;
- ppc_md.init_ras_IRQ = NULL;
ppc_md.get_irq = iSeries_get_irq;
ppc_md.init = NULL;
@@ -860,7 +860,7 @@
{
if ( dprof_buffer ) {
unsigned i;
- for (i=0; i<MAX_PACAS; ++i) {
+ for (i=0; i<NR_CPUS; ++i) {
paca[i].prof_shift = dprof_shift;
paca[i].prof_len = dprof_len-1;
paca[i].prof_buffer = dprof_buffer;
diff -Nru a/arch/ppc64/kernel/ioctl32.c b/arch/ppc64/kernel/ioctl32.c
--- a/arch/ppc64/kernel/ioctl32.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/ioctl32.c Thu Jun 19 00:45:34 2003
@@ -20,813 +20,13 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/compat.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/ioctl.h>
-#include <linux/if.h>
-#include <linux/slab.h>
-#include <linux/hdreg.h>
-#include <linux/raid/md.h>
-#include <linux/kd.h>
-#include <linux/route.h>
-#include <linux/in6.h>
-#include <linux/ipv6_route.h>
-#include <linux/skbuff.h>
-#include <linux/netlink.h>
-#include <linux/vt.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/fd.h>
-#include <linux/ppp_defs.h>
-#include <linux/if_ppp.h>
-#include <linux/if_pppox.h>
-#include <linux/if_tun.h>
-#include <linux/mtio.h>
-#include <linux/cdrom.h>
-#include <linux/loop.h>
-#include <linux/auto_fs.h>
-#include <linux/devfs_fs.h>
-#include <linux/tty.h>
-#include <linux/vt_kern.h>
-#include <linux/fb.h>
-#include <linux/ext2_fs.h>
-#include <linux/videodev.h>
-#include <linux/netdevice.h>
-#include <linux/raw.h>
-#include <linux/smb_fs.h>
+#define INCLUDES
+#include "compat_ioctl.c"
#include <linux/ncp_fs.h>
-#include <linux/blkpg.h>
-#include <linux/blk.h>
-#include <linux/elevator.h>
-#include <linux/rtc.h>
-#include <linux/pci.h>
-#include <linux/dm-ioctl.h>
-
-#include <scsi/scsi.h>
-/* Ugly hack. */
-#undef __KERNEL__
-#include <scsi/scsi_ioctl.h>
-#define __KERNEL__
-#include <scsi/sg.h>
-
-#include <asm/types.h>
-#include <asm/uaccess.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#include <linux/if_bonding.h>
-#include <asm/module.h>
-#include <linux/soundcard.h>
-#include <linux/watchdog.h>
-#include <linux/lp.h>
-
-#include <linux/atm.h>
-#include <linux/atmarp.h>
-#include <linux/atmclip.h>
-#include <linux/atmdev.h>
-#include <linux/atmioc.h>
-#include <linux/atmlec.h>
-#include <linux/atmmpc.h>
-#include <linux/atmsvc.h>
-#include <linux/atm_tcp.h>
-#include <linux/sonet.h>
-#include <linux/atm_suni.h>
-#include <linux/mtd/mtd.h>
-
-#include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/hci.h>
-#include <net/bluetooth/rfcomm.h>
-
-#include <linux/usb.h>
-#include <linux/usbdevice_fs.h>
-#include <linux/nbd.h>
-#include <linux/random.h>
#include <asm/ppc32.h>
-#include <asm/ppcdebug.h>
-/* Aiee. Someone does not find a difference between int and long */
-#define EXT2_IOC32_GETFLAGS _IOR('f', 1, int)
-#define EXT2_IOC32_SETFLAGS _IOW('f', 2, int)
-#define EXT2_IOC32_GETVERSION _IOR('v', 1, int)
-#define EXT2_IOC32_SETVERSION _IOW('v', 2, int)
-
-extern asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
-
-static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- int err;
- unsigned long val;
-
- set_fs (KERNEL_DS);
- err = sys_ioctl(fd, cmd, (unsigned long)&val);
- set_fs (old_fs);
- if (!err && put_user(val, (u32 *)arg))
- return -EFAULT;
- return err;
-}
-
-static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- int err;
- unsigned long val;
-
- if (get_user(val, (u32 *)arg))
- return -EFAULT;
- set_fs (KERNEL_DS);
- err = sys_ioctl(fd, cmd, (unsigned long)&val);
- set_fs (old_fs);
- if (!err && put_user(val, (u32 *)arg))
- return -EFAULT;
- return err;
-}
-
-static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- /* These are just misnamed, they actually get/put from/to user an int */
- switch (cmd) {
- case EXT2_IOC32_GETFLAGS: cmd = EXT2_IOC_GETFLAGS; break;
- case EXT2_IOC32_SETFLAGS: cmd = EXT2_IOC_SETFLAGS; break;
- case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break;
- case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break;
- }
- return sys_ioctl(fd, cmd, arg);
-}
-
-struct video_tuner32 {
- s32 tuner;
- u8 name[32];
- u32 rangelow, rangehigh;
- u32 flags;
- u16 mode, signal;
-};
-
-static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 *up)
-{
- int i;
-
- if (get_user(kp->tuner, &up->tuner))
- return -EFAULT;
- for(i = 0; i < 32; i++)
- __get_user(kp->name[i], &up->name[i]);
- __get_user(kp->rangelow, &up->rangelow);
- __get_user(kp->rangehigh, &up->rangehigh);
- __get_user(kp->flags, &up->flags);
- __get_user(kp->mode, &up->mode);
- __get_user(kp->signal, &up->signal);
- return 0;
-}
-
-static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 *up)
-{
- int i;
-
- if (put_user(kp->tuner, &up->tuner))
- return -EFAULT;
- for(i = 0; i < 32; i++)
- __put_user(kp->name[i], &up->name[i]);
- __put_user(kp->rangelow, &up->rangelow);
- __put_user(kp->rangehigh, &up->rangehigh);
- __put_user(kp->flags, &up->flags);
- __put_user(kp->mode, &up->mode);
- __put_user(kp->signal, &up->signal);
- return 0;
-}
-
-struct video_buffer32 {
- /* void * */ u32 base;
- s32 height, width, depth, bytesperline;
-};
-
-static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 *up)
-{
- u32 tmp;
-
- if (get_user(tmp, &up->base))
- return -EFAULT;
- kp->base = (void *) ((unsigned long)tmp);
- __get_user(kp->height, &up->height);
- __get_user(kp->width, &up->width);
- __get_user(kp->depth, &up->depth);
- __get_user(kp->bytesperline, &up->bytesperline);
- return 0;
-}
-
-static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 *up)
-{
- u32 tmp = (u32)((unsigned long)kp->base);
-
- if (put_user(tmp, &up->base))
- return -EFAULT;
- __put_user(kp->height, &up->height);
- __put_user(kp->width, &up->width);
- __put_user(kp->depth, &up->depth);
- __put_user(kp->bytesperline, &up->bytesperline);
- return 0;
-}
-
-struct video_clip32 {
- s32 x, y, width, height;
- /* struct video_clip32 * */ u32 next;
-};
-
-struct video_window32 {
- u32 x, y, width, height, chromakey, flags;
- /* struct video_clip32 * */ u32 clips;
- s32 clipcount;
-};
-
-static void free_kvideo_clips(struct video_window *kp)
-{
- struct video_clip *cp;
-
- cp = kp->clips;
- if (cp != NULL)
- kfree(cp);
-}
-
-static int get_video_window32(struct video_window *kp, struct video_window32 *up)
-{
- struct video_clip32 *ucp;
- struct video_clip *kcp;
- int nclips, err, i;
- u32 tmp;
-
- if (get_user(kp->x, &up->x))
- return -EFAULT;
- __get_user(kp->y, &up->y);
- __get_user(kp->width, &up->width);
- __get_user(kp->height, &up->height);
- __get_user(kp->chromakey, &up->chromakey);
- __get_user(kp->flags, &up->flags);
- __get_user(kp->clipcount, &up->clipcount);
- __get_user(tmp, &up->clips);
- ucp = (struct video_clip32 *)A(tmp);
- kp->clips = NULL;
-
- nclips = kp->clipcount;
- if (nclips == 0)
- return 0;
-
- if (ucp == 0)
- return -EINVAL;
-
- /* Peculiar interface... */
- if (nclips < 0)
- nclips = VIDEO_CLIPMAP_SIZE;
-
- kcp = kmalloc(nclips * sizeof(struct video_clip), GFP_KERNEL);
- err = -ENOMEM;
- if (kcp == NULL)
- goto cleanup_and_err;
-
- kp->clips = kcp;
- for(i = 0; i < nclips; i++) {
- __get_user(kcp[i].x, &ucp[i].x);
- __get_user(kcp[i].y, &ucp[i].y);
- __get_user(kcp[i].width, &ucp[i].width);
- __get_user(kcp[i].height, &ucp[i].height);
- kcp[nclips].next = NULL;
- }
-
- return 0;
-
-cleanup_and_err:
- free_kvideo_clips(kp);
- return err;
-}
-
-/* You get back everything except the clips... */
-static int put_video_window32(struct video_window *kp, struct video_window32 *up)
-{
- if (put_user(kp->x, &up->x))
- return -EFAULT;
- __put_user(kp->y, &up->y);
- __put_user(kp->width, &up->width);
- __put_user(kp->height, &up->height);
- __put_user(kp->chromakey, &up->chromakey);
- __put_user(kp->flags, &up->flags);
- __put_user(kp->clipcount, &up->clipcount);
- return 0;
-}
-
-#define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32)
-#define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32)
-#define VIDIOCGWIN32 _IOR('v',9, struct video_window32)
-#define VIDIOCSWIN32 _IOW('v',10, struct video_window32)
-#define VIDIOCGFBUF32 _IOR('v',11, struct video_buffer32)
-#define VIDIOCSFBUF32 _IOW('v',12, struct video_buffer32)
-#define VIDIOCGFREQ32 _IOR('v',14, u32)
-#define VIDIOCSFREQ32 _IOW('v',15, u32)
-
-static int do_video_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- union {
- struct video_tuner vt;
- struct video_buffer vb;
- struct video_window vw;
- unsigned long vx;
- } karg;
- mm_segment_t old_fs = get_fs();
- void *up = (void *)arg;
- int err = 0;
-
- /* First, convert the command. */
- switch(cmd) {
- case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break;
- case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break;
- case VIDIOCGWIN32: cmd = VIDIOCGWIN; break;
- case VIDIOCSWIN32: cmd = VIDIOCSWIN; break;
- case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break;
- case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break;
- case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break;
- case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break;
- };
-
- switch(cmd) {
- case VIDIOCSTUNER:
- case VIDIOCGTUNER:
- err = get_video_tuner32(&karg.vt, up);
- break;
-
- case VIDIOCSWIN:
- err = get_video_window32(&karg.vw, up);
- break;
-
- case VIDIOCSFBUF:
- err = get_video_buffer32(&karg.vb, up);
- break;
-
- case VIDIOCSFREQ:
- err = get_user(karg.vx, (u32 *)up);
- break;
- };
- if (err)
- goto out;
-
- set_fs(KERNEL_DS);
- err = sys_ioctl(fd, cmd, (unsigned long)&karg);
- set_fs(old_fs);
-
- if (cmd == VIDIOCSWIN)
- free_kvideo_clips(&karg.vw);
-
- if (err == 0) {
- switch(cmd) {
- case VIDIOCGTUNER:
- err = put_video_tuner32(&karg.vt, up);
- break;
-
- case VIDIOCGWIN:
- err = put_video_window32(&karg.vw, up);
- break;
-
- case VIDIOCGFBUF:
- err = put_video_buffer32(&karg.vb, up);
- break;
-
- case VIDIOCGFREQ:
- err = put_user(((u32)karg.vx), (u32 *)up);
- break;
- };
- }
-out:
- return err;
-}
-
-static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct compat_timeval *up = (struct compat_timeval *)arg;
- struct timeval ktv;
- mm_segment_t old_fs = get_fs();
- int err;
-
- set_fs(KERNEL_DS);
- err = sys_ioctl(fd, cmd, (unsigned long)&ktv);
- set_fs(old_fs);
- if (!err) {
- err = put_user(ktv.tv_sec, &up->tv_sec);
- err |= __put_user(ktv.tv_usec, &up->tv_usec);
- }
- return err;
-}
-
-struct ifmap32 {
- u32 mem_start;
- u32 mem_end;
- unsigned short base_addr;
- unsigned char irq;
- unsigned char dma;
- unsigned char port;
-};
-
-struct ifreq32 {
-#define IFHWADDRLEN 6
-#define IFNAMSIZ 16
- union {
- char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
- } ifr_ifrn;
- union {
- struct sockaddr ifru_addr;
- struct sockaddr ifru_dstaddr;
- struct sockaddr ifru_broadaddr;
- struct sockaddr ifru_netmask;
- struct sockaddr ifru_hwaddr;
- short ifru_flags;
- int ifru_ivalue;
- int ifru_mtu;
- struct ifmap32 ifru_map;
- char ifru_slave[IFNAMSIZ]; /* Just fits the size */
- char ifru_newname[IFNAMSIZ];
- compat_caddr_t ifru_data;
- } ifr_ifru;
-};
-
-struct ifconf32 {
- int ifc_len; /* size of buffer */
- compat_caddr_t ifcbuf;
-};
-
-#ifdef CONFIG_NET
-static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct net_device *dev;
- struct ifreq32 ifr32;
- int err;
-
- if (copy_from_user(&ifr32, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
- return -EFAULT;
-
- dev = dev_get_by_index(ifr32.ifr_ifindex);
- if (!dev)
- return -ENODEV;
-
- strcpy(ifr32.ifr_name, dev->name);
- dev_put(dev);
-
- err = copy_to_user((struct ifreq32 *)arg, &ifr32, sizeof(struct ifreq32));
- return (err ? -EFAULT : 0);
-}
-#endif
-
-static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct ifconf32 ifc32;
- struct ifconf ifc;
- struct ifreq32 *ifr32;
- struct ifreq *ifr;
- mm_segment_t old_fs;
- unsigned int i, j;
- int err;
-
- if (copy_from_user(&ifc32, (struct ifconf32 *)arg, sizeof(struct ifconf32)))
- return -EFAULT;
-
- if (ifc32.ifcbuf == 0) {
- ifc32.ifc_len = 0;
- ifc.ifc_len = 0;
- ifc.ifc_buf = NULL;
- } else {
- ifc.ifc_len = ((ifc32.ifc_len / sizeof (struct ifreq32)) + 1) *
- sizeof (struct ifreq);
- ifc.ifc_buf = kmalloc (ifc.ifc_len, GFP_KERNEL);
- if (!ifc.ifc_buf)
- return -ENOMEM;
- }
- ifr = ifc.ifc_req;
- ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);
- for (i = 0; i < ifc32.ifc_len; i += sizeof (struct ifreq32)) {
- if (copy_from_user(ifr++, ifr32++, sizeof (struct ifreq32))) {
- kfree (ifc.ifc_buf);
- return -EFAULT;
- }
- }
- old_fs = get_fs(); set_fs (KERNEL_DS);
- err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc);
- set_fs (old_fs);
- if (!err) {
- ifr = ifc.ifc_req;
- ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);
- for (i = 0, j = 0; i < ifc32.ifc_len && j < ifc.ifc_len;
- i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) {
- if (copy_to_user(ifr32++, ifr++, sizeof (struct ifreq32))) {
- err = -EFAULT;
- break;
- }
- }
- if (!err) {
- if (ifc32.ifcbuf == 0) {
- /* Translate from 64-bit structure multiple to
- * a 32-bit one.
- */
- i = ifc.ifc_len;
- i = ((i / sizeof(struct ifreq)) * sizeof(struct ifreq32));
- ifc32.ifc_len = i;
- } else {
- if (i <= ifc32.ifc_len)
- ifc32.ifc_len = i;
- else
- ifc32.ifc_len = i - sizeof (struct ifreq32);
- }
- if (copy_to_user((struct ifconf32 *)arg, &ifc32, sizeof(struct ifconf32)))
- err = -EFAULT;
- }
- }
- if (ifc.ifc_buf != NULL)
- kfree (ifc.ifc_buf);
- return err;
-}
-
-static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct ifreq ifr;
- mm_segment_t old_fs;
- int err, len;
- u32 data, ethcmd;
-
- if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
- return -EFAULT;
- ifr.ifr_data = (__kernel_caddr_t)get_zeroed_page(GFP_KERNEL);
- if (!ifr.ifr_data)
- return -EAGAIN;
-
- __get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
-
- if (get_user(ethcmd, (u32 *)A(data))) {
- err = -EFAULT;
- goto out;
- }
- switch (ethcmd) {
- case ETHTOOL_GDRVINFO: len = sizeof(struct ethtool_drvinfo); break;
- case ETHTOOL_GMSGLVL:
- case ETHTOOL_SMSGLVL:
- case ETHTOOL_GLINK:
- case ETHTOOL_NWAY_RST: len = sizeof(struct ethtool_value); break;
- case ETHTOOL_GREGS: {
- struct ethtool_regs *regaddr = (struct ethtool_regs *)A(data);
- /* darned variable size arguments */
- if (get_user(len, (u32 *)®addr->len)) {
- err = -EFAULT;
- goto out;
- }
- len += sizeof(struct ethtool_regs);
- break;
- }
- case ETHTOOL_GSET:
- case ETHTOOL_SSET: len = sizeof(struct ethtool_cmd); break;
- default:
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) {
- err = -EFAULT;
- goto out;
- }
-
- old_fs = get_fs();
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
- set_fs (old_fs);
- if (!err) {
- u32 data;
-
- __get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
- len = copy_to_user((char *)A(data), ifr.ifr_data, len);
- if (len)
- err = -EFAULT;
- }
-
-out:
- free_page((unsigned long)ifr.ifr_data);
- return err;
-}
-
-static int bond_ioctl(unsigned long fd, unsigned int cmd, unsigned long arg)
-{
- struct ifreq ifr;
- mm_segment_t old_fs;
- int err, len;
- u32 data;
-
- if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
- return -EFAULT;
- ifr.ifr_data = (__kernel_caddr_t)get_zeroed_page(GFP_KERNEL);
- if (!ifr.ifr_data)
- return -EAGAIN;
-
- switch (cmd) {
- case SIOCBONDENSLAVE:
- case SIOCBONDRELEASE:
- case SIOCBONDSETHWADDR:
- case SIOCBONDCHANGEACTIVE:
- len = IFNAMSIZ * sizeof(char);
- break;
- case SIOCBONDSLAVEINFOQUERY:
- len = sizeof(struct ifslave);
- break;
- case SIOCBONDINFOQUERY:
- len = sizeof(struct ifbond);
- break;
- default:
- err = -EINVAL;
- goto out;
- };
-
- __get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
- if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) {
- err = -EFAULT;
- goto out;
- }
-
- old_fs = get_fs();
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
- set_fs (old_fs);
- if (!err) {
- len = copy_to_user((char *)A(data), ifr.ifr_data, len);
- if (len)
- err = -EFAULT;
- }
-
-out:
- free_page((unsigned long)ifr.ifr_data);
- return err;
-}
-
-static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct ifreq ifr;
- mm_segment_t old_fs;
- int err;
-
- switch (cmd) {
- case SIOCSIFMAP:
- err = copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(ifr.ifr_name));
- err |= __get_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
- err |= __get_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));
- err |= __get_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));
- err |= __get_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));
- err |= __get_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));
- err |= __get_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));
- if (err)
- return -EFAULT;
- break;
- default:
- if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
- return -EFAULT;
- break;
- }
- old_fs = get_fs();
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
- set_fs (old_fs);
- if (!err) {
- switch (cmd) {
- case SIOCGIFFLAGS:
- case SIOCGIFMETRIC:
- case SIOCGIFMTU:
- case SIOCGIFMEM:
- case SIOCGIFHWADDR:
- case SIOCGIFINDEX:
- case SIOCGIFADDR:
- case SIOCGIFBRDADDR:
- case SIOCGIFDSTADDR:
- case SIOCGIFNETMASK:
- case SIOCGIFTXQLEN:
- if (copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(struct ifreq32)))
- return -EFAULT;
- break;
- case SIOCGIFMAP:
- err = copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(ifr.ifr_name));
- err |= __put_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
- err |= __put_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));
- err |= __put_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));
- err |= __put_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));
- err |= __put_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));
- err |= __put_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));
- if (err)
- err = -EFAULT;
- break;
- }
- }
- return err;
-}
-
-struct rtentry32 {
- u32 rt_pad1;
- struct sockaddr rt_dst; /* target address */
- struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */
- struct sockaddr rt_genmask; /* target network mask (IP) */
- unsigned short rt_flags;
- short rt_pad2;
- u32 rt_pad3;
- unsigned char rt_tos;
- unsigned char rt_class;
- short rt_pad4;
- short rt_metric; /* +1 for binary compatibility! */
- /* char * */ u32 rt_dev; /* forcing the device at add */
- u32 rt_mtu; /* per route MTU/Window */
- u32 rt_window; /* Window clamping */
- unsigned short rt_irtt; /* Initial RTT */
-
-};
-
-struct in6_rtmsg32 {
- struct in6_addr rtmsg_dst;
- struct in6_addr rtmsg_src;
- struct in6_addr rtmsg_gateway;
- u32 rtmsg_type;
- u16 rtmsg_dst_len;
- u16 rtmsg_src_len;
- u32 rtmsg_metric;
- u32 rtmsg_info;
- u32 rtmsg_flags;
- s32 rtmsg_ifindex;
-};
-
-static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- int ret;
- void *r = NULL;
- struct in6_rtmsg r6;
- struct rtentry r4;
- char devname[16];
- u32 rtdev;
- mm_segment_t old_fs = get_fs();
-
- struct socket *mysock = sockfd_lookup(fd, &ret);
-
- if (mysock && mysock->sk && mysock->sk->family == AF_INET6) { /* ipv6 */
- ret = copy_from_user (&r6.rtmsg_dst, &(((struct in6_rtmsg32 *)arg)->rtmsg_dst),
- 3 * sizeof(struct in6_addr));
- ret |= __get_user (r6.rtmsg_type, &(((struct in6_rtmsg32 *)arg)->rtmsg_type));
- ret |= __get_user (r6.rtmsg_dst_len, &(((struct in6_rtmsg32 *)arg)->rtmsg_dst_len));
- ret |= __get_user (r6.rtmsg_src_len, &(((struct in6_rtmsg32 *)arg)->rtmsg_src_len));
- ret |= __get_user (r6.rtmsg_metric, &(((struct in6_rtmsg32 *)arg)->rtmsg_metric));
- ret |= __get_user (r6.rtmsg_info, &(((struct in6_rtmsg32 *)arg)->rtmsg_info));
- ret |= __get_user (r6.rtmsg_flags, &(((struct in6_rtmsg32 *)arg)->rtmsg_flags));
- ret |= __get_user (r6.rtmsg_ifindex, &(((struct in6_rtmsg32 *)arg)->rtmsg_ifindex));
-
- r = (void *) &r6;
- } else { /* ipv4 */
- ret = copy_from_user (&r4.rt_dst, &(((struct rtentry32 *)arg)->rt_dst), 3 * sizeof(struct sockaddr));
- ret |= __get_user (r4.rt_flags, &(((struct rtentry32 *)arg)->rt_flags));
- ret |= __get_user (r4.rt_metric, &(((struct rtentry32 *)arg)->rt_metric));
- ret |= __get_user (r4.rt_mtu, &(((struct rtentry32 *)arg)->rt_mtu));
- ret |= __get_user (r4.rt_window, &(((struct rtentry32 *)arg)->rt_window));
- ret |= __get_user (r4.rt_irtt, &(((struct rtentry32 *)arg)->rt_irtt));
- ret |= __get_user (rtdev, &(((struct rtentry32 *)arg)->rt_dev));
- if (rtdev) {
- ret |= copy_from_user (devname, (char *)A(rtdev), 15);
- r4.rt_dev = devname; devname[15] = 0;
- } else
- r4.rt_dev = 0;
-
- r = (void *) &r4;
- }
-
- if (ret)
- return -EFAULT;
-
- set_fs (KERNEL_DS);
- ret = sys_ioctl (fd, cmd, (long) r);
- set_fs (old_fs);
-
- if (mysock)
- sockfd_put(mysock);
-
- return ret;
-}
-
-struct hd_geometry32 {
- unsigned char heads;
- unsigned char sectors;
- unsigned short cylinders;
- u32 start;
-};
-
-static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- struct hd_geometry geo;
- int err;
-
- set_fs (KERNEL_DS);
- err = sys_ioctl(fd, HDIO_GETGEO, (unsigned long)&geo);
- set_fs (old_fs);
- if (!err) {
- if (copy_to_user ((struct hd_geometry32 *)arg, &geo, 4) ||
- __put_user (geo.start, &(((struct hd_geometry32 *)arg)->start)))
- err = -EFAULT;
- }
- return err;
-}
+#define CODE
+#include "compat_ioctl.c"
struct hd_big_geometry32 {
unsigned char heads;
@@ -856,1210 +56,6 @@
return err;
}
-static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- unsigned long kval;
- unsigned int *uvp;
- int error;
-
- set_fs(KERNEL_DS);
- error = sys_ioctl(fd, cmd, (long)&kval);
- set_fs(old_fs);
-
- if (error == 0) {
- uvp = (unsigned int *)arg;
- if (put_user(kval, uvp))
- error = -EFAULT;
- }
- return error;
-}
-
-struct floppy_struct32 {
- unsigned int size;
- unsigned int sect;
- unsigned int head;
- unsigned int track;
- unsigned int stretch;
- unsigned char gap;
- unsigned char rate;
- unsigned char spec1;
- unsigned char fmt_gap;
- const compat_caddr_t name;
-};
-
-struct floppy_drive_params32 {
- char cmos;
- u32 max_dtr;
- u32 hlt;
- u32 hut;
- u32 srt;
- u32 spinup;
- u32 spindown;
- unsigned char spindown_offset;
- unsigned char select_delay;
- unsigned char rps;
- unsigned char tracks;
- u32 timeout;
- unsigned char interleave_sect;
- struct floppy_max_errors max_errors;
- char flags;
- char read_track;
- short autodetect[8];
- int checkfreq;
- int native_format;
-};
-
-struct floppy_drive_struct32 {
- signed char flags;
- u32 spinup_date;
- u32 select_date;
- u32 first_read_date;
- short probed_format;
- short track;
- short maxblock;
- short maxtrack;
- int generation;
- int keep_data;
- int fd_ref;
- int fd_device;
- int last_checked;
- compat_caddr_t dmabuf;
- int bufblocks;
-};
-
-struct floppy_fdc_state32 {
- int spec1;
- int spec2;
- int dtr;
- unsigned char version;
- unsigned char dor;
- u32 address;
- unsigned int rawcmd:2;
- unsigned int reset:1;
- unsigned int need_configure:1;
- unsigned int perp_mode:2;
- unsigned int has_fifo:1;
- unsigned int driver_version;
- unsigned char track[4];
-};
-
-struct floppy_write_errors32 {
- unsigned int write_errors;
- u32 first_error_sector;
- int first_error_generation;
- u32 last_error_sector;
- int last_error_generation;
- unsigned int badness;
-};
-
-#define FDSETPRM32 _IOW(2, 0x42, struct floppy_struct32)
-#define FDDEFPRM32 _IOW(2, 0x43, struct floppy_struct32)
-#define FDGETPRM32 _IOR(2, 0x04, struct floppy_struct32)
-#define FDSETDRVPRM32 _IOW(2, 0x90, struct floppy_drive_params32)
-#define FDGETDRVPRM32 _IOR(2, 0x11, struct floppy_drive_params32)
-#define FDGETDRVSTAT32 _IOR(2, 0x12, struct floppy_drive_struct32)
-#define FDPOLLDRVSTAT32 _IOR(2, 0x13, struct floppy_drive_struct32)
-#define FDGETFDCSTAT32 _IOR(2, 0x15, struct floppy_fdc_state32)
-#define FDWERRORGET32 _IOR(2, 0x17, struct floppy_write_errors32)
-
-static struct {
- unsigned int cmd32;
- unsigned int cmd;
-} fd_ioctl_trans_table[] = {
- { FDSETPRM32, FDSETPRM },
- { FDDEFPRM32, FDDEFPRM },
- { FDGETPRM32, FDGETPRM },
- { FDSETDRVPRM32, FDSETDRVPRM },
- { FDGETDRVPRM32, FDGETDRVPRM },
- { FDGETDRVSTAT32, FDGETDRVSTAT },
- { FDPOLLDRVSTAT32, FDPOLLDRVSTAT },
- { FDGETFDCSTAT32, FDGETFDCSTAT },
- { FDWERRORGET32, FDWERRORGET }
-};
-
-#define NR_FD_IOCTL_TRANS (sizeof(fd_ioctl_trans_table)/sizeof(fd_ioctl_trans_table[0]))
-
-static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- void *karg = NULL;
- unsigned int kcmd = 0;
- int i, err;
-
- for (i = 0; i < NR_FD_IOCTL_TRANS; i++)
- if (cmd == fd_ioctl_trans_table[i].cmd32) {
- kcmd = fd_ioctl_trans_table[i].cmd;
- break;
- }
- if (!kcmd)
- return -EINVAL;
-
- switch (cmd) {
- case FDSETPRM32:
- case FDDEFPRM32:
- case FDGETPRM32:
- {
- struct floppy_struct *f;
-
- f = karg = kmalloc(sizeof(struct floppy_struct), GFP_KERNEL);
- if (!karg)
- return -ENOMEM;
- if (cmd == FDGETPRM32)
- break;
- err = __get_user(f->size, &((struct floppy_struct32 *)arg)->size);
- err |= __get_user(f->sect, &((struct floppy_struct32 *)arg)->sect);
- err |= __get_user(f->head, &((struct floppy_struct32 *)arg)->head);
- err |= __get_user(f->track, &((struct floppy_struct32 *)arg)->track);
- err |= __get_user(f->stretch, &((struct floppy_struct32 *)arg)->stretch);
- err |= __get_user(f->gap, &((struct floppy_struct32 *)arg)->gap);
- err |= __get_user(f->rate, &((struct floppy_struct32 *)arg)->rate);
- err |= __get_user(f->spec1, &((struct floppy_struct32 *)arg)->spec1);
- err |= __get_user(f->fmt_gap, &((struct floppy_struct32 *)arg)->fmt_gap);
- err |= __get_user((u64)f->name, &((struct floppy_struct32 *)arg)->name);
- if (err) {
- err = -EFAULT;
- goto out;
- }
- break;
- }
- case FDSETDRVPRM32:
- case FDGETDRVPRM32:
- {
- struct floppy_drive_params *f;
-
- f = karg = kmalloc(sizeof(struct floppy_drive_params), GFP_KERNEL);
- if (!karg)
- return -ENOMEM;
- if (cmd == FDGETDRVPRM32)
- break;
- err = __get_user(f->cmos, &((struct floppy_drive_params32 *)arg)->cmos);
- err |= __get_user(f->max_dtr, &((struct floppy_drive_params32 *)arg)->max_dtr);
- err |= __get_user(f->hlt, &((struct floppy_drive_params32 *)arg)->hlt);
- err |= __get_user(f->hut, &((struct floppy_drive_params32 *)arg)->hut);
- err |= __get_user(f->srt, &((struct floppy_drive_params32 *)arg)->srt);
- err |= __get_user(f->spinup, &((struct floppy_drive_params32 *)arg)->spinup);
- err |= __get_user(f->spindown, &((struct floppy_drive_params32 *)arg)->spindown);
- err |= __get_user(f->spindown_offset, &((struct floppy_drive_params32 *)arg)->spindown_offset);
- err |= __get_user(f->select_delay, &((struct floppy_drive_params32 *)arg)->select_delay);
- err |= __get_user(f->rps, &((struct floppy_drive_params32 *)arg)->rps);
- err |= __get_user(f->tracks, &((struct floppy_drive_params32 *)arg)->tracks);
- err |= __get_user(f->timeout, &((struct floppy_drive_params32 *)arg)->timeout);
- err |= __get_user(f->interleave_sect, &((struct floppy_drive_params32 *)arg)->interleave_sect);
- err |= __copy_from_user(&f->max_errors, &((struct floppy_drive_params32 *)arg)->max_errors, sizeof(f->max_errors));
- err |= __get_user(f->flags, &((struct floppy_drive_params32 *)arg)->flags);
- err |= __get_user(f->read_track, &((struct floppy_drive_params32 *)arg)->read_track);
- err |= __copy_from_user(f->autodetect, ((struct floppy_drive_params32 *)arg)->autodetect, sizeof(f->autodetect));
- err |= __get_user(f->checkfreq, &((struct floppy_drive_params32 *)arg)->checkfreq);
- err |= __get_user(f->native_format, &((struct floppy_drive_params32 *)arg)->native_format);
- if (err) {
- err = -EFAULT;
- goto out;
- }
- break;
- }
- case FDGETDRVSTAT32:
- case FDPOLLDRVSTAT32:
- karg = kmalloc(sizeof(struct floppy_drive_struct), GFP_KERNEL);
- if (!karg)
- return -ENOMEM;
- break;
- case FDGETFDCSTAT32:
- karg = kmalloc(sizeof(struct floppy_fdc_state), GFP_KERNEL);
- if (!karg)
- return -ENOMEM;
- break;
- case FDWERRORGET32:
- karg = kmalloc(sizeof(struct floppy_write_errors), GFP_KERNEL);
- if (!karg)
- return -ENOMEM;
- break;
- default:
- return -EINVAL;
- }
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, kcmd, (unsigned long)karg);
- set_fs (old_fs);
- if (err)
- goto out;
- switch (cmd) {
- case FDGETPRM32:
- {
- struct floppy_struct *f = karg;
-
- err = __put_user(f->size, &((struct floppy_struct32 *)arg)->size);
- err |= __put_user(f->sect, &((struct floppy_struct32 *)arg)->sect);
- err |= __put_user(f->head, &((struct floppy_struct32 *)arg)->head);
- err |= __put_user(f->track, &((struct floppy_struct32 *)arg)->track);
- err |= __put_user(f->stretch, &((struct floppy_struct32 *)arg)->stretch);
- err |= __put_user(f->gap, &((struct floppy_struct32 *)arg)->gap);
- err |= __put_user(f->rate, &((struct floppy_struct32 *)arg)->rate);
- err |= __put_user(f->spec1, &((struct floppy_struct32 *)arg)->spec1);
- err |= __put_user(f->fmt_gap, &((struct floppy_struct32 *)arg)->fmt_gap);
- err |= __put_user((u64)f->name, &((struct floppy_struct32 *)arg)->name);
- break;
- }
- case FDGETDRVPRM32:
- {
- struct floppy_drive_params *f = karg;
-
- err = __put_user(f->cmos, &((struct floppy_drive_params32 *)arg)->cmos);
- err |= __put_user(f->max_dtr, &((struct floppy_drive_params32 *)arg)->max_dtr);
- err |= __put_user(f->hlt, &((struct floppy_drive_params32 *)arg)->hlt);
- err |= __put_user(f->hut, &((struct floppy_drive_params32 *)arg)->hut);
- err |= __put_user(f->srt, &((struct floppy_drive_params32 *)arg)->srt);
- err |= __put_user(f->spinup, &((struct floppy_drive_params32 *)arg)->spinup);
- err |= __put_user(f->spindown, &((struct floppy_drive_params32 *)arg)->spindown);
- err |= __put_user(f->spindown_offset, &((struct floppy_drive_params32 *)arg)->spindown_offset);
- err |= __put_user(f->select_delay, &((struct floppy_drive_params32 *)arg)->select_delay);
- err |= __put_user(f->rps, &((struct floppy_drive_params32 *)arg)->rps);
- err |= __put_user(f->tracks, &((struct floppy_drive_params32 *)arg)->tracks);
- err |= __put_user(f->timeout, &((struct floppy_drive_params32 *)arg)->timeout);
- err |= __put_user(f->interleave_sect, &((struct floppy_drive_params32 *)arg)->interleave_sect);
- err |= __copy_to_user(&((struct floppy_drive_params32 *)arg)->max_errors, &f->max_errors, sizeof(f->max_errors));
- err |= __put_user(f->flags, &((struct floppy_drive_params32 *)arg)->flags);
- err |= __put_user(f->read_track, &((struct floppy_drive_params32 *)arg)->read_track);
- err |= __copy_to_user(((struct floppy_drive_params32 *)arg)->autodetect, f->autodetect, sizeof(f->autodetect));
- err |= __put_user(f->checkfreq, &((struct floppy_drive_params32 *)arg)->checkfreq);
- err |= __put_user(f->native_format, &((struct floppy_drive_params32 *)arg)->native_format);
- break;
- }
- case FDGETDRVSTAT32:
- case FDPOLLDRVSTAT32:
- {
- struct floppy_drive_struct *f = karg;
-
- err = __put_user(f->flags, &((struct floppy_drive_struct32 *)arg)->flags);
- err |= __put_user(f->spinup_date, &((struct floppy_drive_struct32 *)arg)->spinup_date);
- err |= __put_user(f->select_date, &((struct floppy_drive_struct32 *)arg)->select_date);
- err |= __put_user(f->first_read_date, &((struct floppy_drive_struct32 *)arg)->first_read_date);
- err |= __put_user(f->probed_format, &((struct floppy_drive_struct32 *)arg)->probed_format);
- err |= __put_user(f->track, &((struct floppy_drive_struct32 *)arg)->track);
- err |= __put_user(f->maxblock, &((struct floppy_drive_struct32 *)arg)->maxblock);
- err |= __put_user(f->maxtrack, &((struct floppy_drive_struct32 *)arg)->maxtrack);
- err |= __put_user(f->generation, &((struct floppy_drive_struct32 *)arg)->generation);
- err |= __put_user(f->keep_data, &((struct floppy_drive_struct32 *)arg)->keep_data);
- err |= __put_user(f->fd_ref, &((struct floppy_drive_struct32 *)arg)->fd_ref);
- err |= __put_user(f->fd_device, &((struct floppy_drive_struct32 *)arg)->fd_device);
- err |= __put_user(f->last_checked, &((struct floppy_drive_struct32 *)arg)->last_checked);
- err |= __put_user((u64)f->dmabuf, &((struct floppy_drive_struct32 *)arg)->dmabuf);
- err |= __put_user((u64)f->bufblocks, &((struct floppy_drive_struct32 *)arg)->bufblocks);
- break;
- }
- case FDGETFDCSTAT32:
- {
- struct floppy_fdc_state *f = karg;
-
- err = __put_user(f->spec1, &((struct floppy_fdc_state32 *)arg)->spec1);
- err |= __put_user(f->spec2, &((struct floppy_fdc_state32 *)arg)->spec2);
- err |= __put_user(f->dtr, &((struct floppy_fdc_state32 *)arg)->dtr);
- err |= __put_user(f->version, &((struct floppy_fdc_state32 *)arg)->version);
- err |= __put_user(f->dor, &((struct floppy_fdc_state32 *)arg)->dor);
- err |= __put_user(f->address, &((struct floppy_fdc_state32 *)arg)->address);
- err |= __copy_to_user((char *)&((struct floppy_fdc_state32 *)arg)->address
- + sizeof(((struct floppy_fdc_state32 *)arg)->address),
- (char *)&f->address + sizeof(f->address), sizeof(int));
- err |= __put_user(f->driver_version, &((struct floppy_fdc_state32 *)arg)->driver_version);
- err |= __copy_to_user(((struct floppy_fdc_state32 *)arg)->track, f->track, sizeof(f->track));
- break;
- }
- case FDWERRORGET32:
- {
- struct floppy_write_errors *f = karg;
-
- err = __put_user(f->write_errors, &((struct floppy_write_errors32 *)arg)->write_errors);
- err |= __put_user(f->first_error_sector, &((struct floppy_write_errors32 *)arg)->first_error_sector);
- err |= __put_user(f->first_error_generation, &((struct floppy_write_errors32 *)arg)->first_error_generation);
- err |= __put_user(f->last_error_sector, &((struct floppy_write_errors32 *)arg)->last_error_sector);
- err |= __put_user(f->last_error_generation, &((struct floppy_write_errors32 *)arg)->last_error_generation);
- err |= __put_user(f->badness, &((struct floppy_write_errors32 *)arg)->badness);
- break;
- }
- default:
- break;
- }
- if (err)
- err = -EFAULT;
-
-out: if (karg) kfree(karg);
- return err;
-}
-
-typedef struct sg_io_hdr32 {
- s32 interface_id; /* [i] 'S' for SCSI generic (required) */
- s32 dxfer_direction; /* [i] data transfer direction */
- u8 cmd_len; /* [i] SCSI command length ( <= 16 bytes) */
- u8 mx_sb_len; /* [i] max length to write to sbp */
- u16 iovec_count; /* [i] 0 implies no scatter gather */
- u32 dxfer_len; /* [i] byte count of data transfer */
- u32 dxferp; /* [i], [*io] points to data transfer memory
- or scatter gather list */
- u32 cmdp; /* [i], [*i] points to command to perform */
- u32 sbp; /* [i], [*o] points to sense_buffer memory */
- u32 timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */
- u32 flags; /* [i] 0 -> default, see SG_FLAG... */
- s32 pack_id; /* [i->o] unused internally (normally) */
- u32 usr_ptr; /* [i->o] unused internally */
- u8 status; /* [o] scsi status */
- u8 masked_status; /* [o] shifted, masked scsi status */
- u8 msg_status; /* [o] messaging level data (optional) */
- u8 sb_len_wr; /* [o] byte count actually written to sbp */
- u16 host_status; /* [o] errors from host adapter */
- u16 driver_status; /* [o] errors from software driver */
- s32 resid; /* [o] dxfer_len - actual_transferred */
- u32 duration; /* [o] time taken by cmd (unit: millisec) */
- u32 info; /* [o] auxiliary information */
-} sg_io_hdr32_t; /* 64 bytes long (on sparc32) */
-
-typedef struct sg_iovec32 {
- u32 iov_base;
- u32 iov_len;
-} sg_iovec32_t;
-
-static int alloc_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32)
-{
- sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32);
- sg_iovec_t *kiov;
- int i;
-
- sgp->dxferp = kmalloc(sgp->iovec_count *
- sizeof(sg_iovec_t), GFP_KERNEL);
- if (!sgp->dxferp)
- return -ENOMEM;
- memset(sgp->dxferp, 0,
- sgp->iovec_count * sizeof(sg_iovec_t));
-
- kiov = (sg_iovec_t *) sgp->dxferp;
- for (i = 0; i < sgp->iovec_count; i++) {
- u32 iov_base32;
- if (__get_user(iov_base32, &uiov->iov_base) ||
- __get_user(kiov->iov_len, &uiov->iov_len))
- return -EFAULT;
-
- kiov->iov_base = kmalloc(kiov->iov_len, GFP_KERNEL);
- if (!kiov->iov_base)
- return -ENOMEM;
- if (copy_from_user(kiov->iov_base,
- (void *) A(iov_base32),
- kiov->iov_len))
- return -EFAULT;
-
- uiov++;
- kiov++;
- }
-
- return 0;
-}
-
-static int copy_back_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32)
-{
- sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32);
- sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp;
- int i;
-
- for (i = 0; i < sgp->iovec_count; i++) {
- u32 iov_base32;
-
- if (__get_user(iov_base32, &uiov->iov_base))
- return -EFAULT;
-
- if (copy_to_user((void *) A(iov_base32),
- kiov->iov_base,
- kiov->iov_len))
- return -EFAULT;
-
- uiov++;
- kiov++;
- }
-
- return 0;
-}
-
-static void free_sg_iovec(sg_io_hdr_t *sgp)
-{
- sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp;
- int i;
-
- for (i = 0; i < sgp->iovec_count; i++) {
- if (kiov->iov_base) {
- kfree(kiov->iov_base);
- kiov->iov_base = NULL;
- }
- kiov++;
- }
- kfree(sgp->dxferp);
- sgp->dxferp = NULL;
-}
-
-static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- sg_io_hdr32_t *sg_io32;
- sg_io_hdr_t sg_io64;
- u32 dxferp32, cmdp32, sbp32;
- mm_segment_t old_fs;
- int err = 0;
-
- sg_io32 = (sg_io_hdr32_t *)arg;
- err = __get_user(sg_io64.interface_id, &sg_io32->interface_id);
- err |= __get_user(sg_io64.dxfer_direction, &sg_io32->dxfer_direction);
- err |= __get_user(sg_io64.cmd_len, &sg_io32->cmd_len);
- err |= __get_user(sg_io64.mx_sb_len, &sg_io32->mx_sb_len);
- err |= __get_user(sg_io64.iovec_count, &sg_io32->iovec_count);
- err |= __get_user(sg_io64.dxfer_len, &sg_io32->dxfer_len);
- err |= __get_user(sg_io64.timeout, &sg_io32->timeout);
- err |= __get_user(sg_io64.flags, &sg_io32->flags);
- err |= __get_user(sg_io64.pack_id, &sg_io32->pack_id);
-
- sg_io64.dxferp = NULL;
- sg_io64.cmdp = NULL;
- sg_io64.sbp = NULL;
-
- err |= __get_user(cmdp32, &sg_io32->cmdp);
- sg_io64.cmdp = kmalloc(sg_io64.cmd_len, GFP_KERNEL);
- if (!sg_io64.cmdp) {
- err = -ENOMEM;
- goto out;
- }
- if (copy_from_user(sg_io64.cmdp,
- (void *) A(cmdp32),
- sg_io64.cmd_len)) {
- err = -EFAULT;
- goto out;
- }
-
- err |= __get_user(sbp32, &sg_io32->sbp);
- sg_io64.sbp = kmalloc(sg_io64.mx_sb_len, GFP_KERNEL);
- if (!sg_io64.sbp) {
- err = -ENOMEM;
- goto out;
- }
- if (copy_from_user(sg_io64.sbp,
- (void *) A(sbp32),
- sg_io64.mx_sb_len)) {
- err = -EFAULT;
- goto out;
- }
-
- err |= __get_user(dxferp32, &sg_io32->dxferp);
- if (sg_io64.iovec_count) {
- int ret;
-
- if ((ret = alloc_sg_iovec(&sg_io64, dxferp32))) {
- err = ret;
- goto out;
- }
- } else {
- sg_io64.dxferp = kmalloc(sg_io64.dxfer_len, GFP_KERNEL);
- if (!sg_io64.dxferp) {
- err = -ENOMEM;
- goto out;
- }
- if (copy_from_user(sg_io64.dxferp,
- (void *) A(dxferp32),
- sg_io64.dxfer_len)) {
- err = -EFAULT;
- goto out;
- }
- }
-
- /* Unused internally, do not even bother to copy it over. */
- sg_io64.usr_ptr = NULL;
-
- if (err)
- return -EFAULT;
-
- old_fs = get_fs();
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long) &sg_io64);
- set_fs (old_fs);
-
- if (err < 0)
- goto out;
-
- err = __put_user(sg_io64.pack_id, &sg_io32->pack_id);
- err |= __put_user(sg_io64.status, &sg_io32->status);
- err |= __put_user(sg_io64.masked_status, &sg_io32->masked_status);
- err |= __put_user(sg_io64.msg_status, &sg_io32->msg_status);
- err |= __put_user(sg_io64.sb_len_wr, &sg_io32->sb_len_wr);
- err |= __put_user(sg_io64.host_status, &sg_io32->host_status);
- err |= __put_user(sg_io64.driver_status, &sg_io32->driver_status);
- err |= __put_user(sg_io64.resid, &sg_io32->resid);
- err |= __put_user(sg_io64.duration, &sg_io32->duration);
- err |= __put_user(sg_io64.info, &sg_io32->info);
- err |= copy_to_user((void *)A(sbp32), sg_io64.sbp, sg_io64.mx_sb_len);
- if (sg_io64.dxferp) {
- if (sg_io64.iovec_count)
- err |= copy_back_sg_iovec(&sg_io64, dxferp32);
- else
- err |= copy_to_user((void *)A(dxferp32),
- sg_io64.dxferp,
- sg_io64.dxfer_len);
- }
- if (err)
- err = -EFAULT;
-
-out:
- if (sg_io64.cmdp)
- kfree(sg_io64.cmdp);
- if (sg_io64.sbp)
- kfree(sg_io64.sbp);
- if (sg_io64.dxferp) {
- if (sg_io64.iovec_count) {
- free_sg_iovec(&sg_io64);
- } else {
- kfree(sg_io64.dxferp);
- }
- }
- return err;
-}
-
-struct ppp_option_data32 {
- compat_caddr_t ptr;
- __u32 length;
- int transmit;
-};
-#define PPPIOCSCOMPRESS32 _IOW('t', 77, struct ppp_option_data32)
-
-struct ppp_idle32 {
- compat_time_t xmit_idle;
- compat_time_t recv_idle;
-};
-#define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32)
-
-static int ppp_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- struct ppp_option_data32 data32;
- struct ppp_option_data data;
- struct ppp_idle32 idle32;
- struct ppp_idle idle;
- unsigned int kcmd;
- void *karg;
- int err = 0;
-
- switch (cmd) {
- case PPPIOCGIDLE32:
- kcmd = PPPIOCGIDLE;
- karg = &idle;
- break;
- case PPPIOCSCOMPRESS32:
- if (copy_from_user(&data32, (struct ppp_option_data32 *)arg, sizeof(struct ppp_option_data32)))
- return -EFAULT;
- data.ptr = kmalloc (data32.length, GFP_KERNEL);
- if (!data.ptr)
- return -ENOMEM;
- if (copy_from_user(data.ptr, (__u8 *)A(data32.ptr), data32.length)) {
- kfree(data.ptr);
- return -EFAULT;
- }
- data.length = data32.length;
- data.transmit = data32.transmit;
- kcmd = PPPIOCSCOMPRESS;
- karg = &data;
- break;
- default:
- do {
- static int count = 0;
- if (++count <= 20)
- printk("ppp_ioctl: Unknown cmd fd(%d) "
- "cmd(%08x) arg(%08x)\n",
- (int)fd, (unsigned int)cmd, (unsigned int)arg);
- } while (0);
- return -EINVAL;
- }
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, kcmd, (unsigned long)karg);
- set_fs (old_fs);
- switch (cmd) {
- case PPPIOCGIDLE32:
- if (err)
- return err;
- idle32.xmit_idle = idle.xmit_idle;
- idle32.recv_idle = idle.recv_idle;
- if (copy_to_user((struct ppp_idle32 *)arg, &idle32, sizeof(struct ppp_idle32)))
- return -EFAULT;
- break;
- case PPPIOCSCOMPRESS32:
- kfree(data.ptr);
- break;
- default:
- break;
- }
- return err;
-}
-
-
-struct mtget32 {
- __u32 mt_type;
- __u32 mt_resid;
- __u32 mt_dsreg;
- __u32 mt_gstat;
- __u32 mt_erreg;
- compat_daddr_t mt_fileno;
- compat_daddr_t mt_blkno;
-};
-#define MTIOCGET32 _IOR('m', 2, struct mtget32)
-
-struct mtpos32 {
- __u32 mt_blkno;
-};
-#define MTIOCPOS32 _IOR('m', 3, struct mtpos32)
-
-struct mtconfiginfo32 {
- __u32 mt_type;
- __u32 ifc_type;
- __u16 irqnr;
- __u16 dmanr;
- __u16 port;
- __u32 debug;
- __u32 have_dens:1;
- __u32 have_bsf:1;
- __u32 have_fsr:1;
- __u32 have_bsr:1;
- __u32 have_eod:1;
- __u32 have_seek:1;
- __u32 have_tell:1;
- __u32 have_ras1:1;
- __u32 have_ras2:1;
- __u32 have_ras3:1;
- __u32 have_qfa:1;
- __u32 pad1:5;
- char reserved[10];
-};
-#define MTIOCGETCONFIG32 _IOR('m', 4, struct mtconfiginfo32)
-#define MTIOCSETCONFIG32 _IOW('m', 5, struct mtconfiginfo32)
-
-static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- struct mtconfiginfo info;
- struct mtget get;
- struct mtpos pos;
- unsigned long kcmd;
- void *karg;
- int err = 0;
-
- switch(cmd) {
- case MTIOCPOS32:
- kcmd = MTIOCPOS;
- karg = &pos;
- break;
- case MTIOCGET32:
- kcmd = MTIOCGET;
- karg = &get;
- break;
- case MTIOCGETCONFIG32:
- kcmd = MTIOCGETCONFIG;
- karg = &info;
- break;
- case MTIOCSETCONFIG32:
- kcmd = MTIOCSETCONFIG;
- karg = &info;
- err = __get_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type);
- err |= __get_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type);
- err |= __get_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr);
- err |= __get_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr);
- err |= __get_user(info.port, &((struct mtconfiginfo32 *)arg)->port);
- err |= __get_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug);
- err |= __copy_from_user((char *)&info.debug + sizeof(info.debug),
- (char *)&((struct mtconfiginfo32 *)arg)->debug
- + sizeof(((struct mtconfiginfo32 *)arg)->debug), sizeof(__u32));
- if (err)
- return -EFAULT;
- break;
- default:
- do {
- static int count = 0;
- if (++count <= 20)
- printk("mt_ioctl: Unknown cmd fd(%d) "
- "cmd(%08x) arg(%08x)\n",
- (int)fd, (unsigned int)cmd, (unsigned int)arg);
- } while (0);
- return -EINVAL;
- }
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, kcmd, (unsigned long)karg);
- set_fs (old_fs);
- if (err)
- return err;
- switch (cmd) {
- case MTIOCPOS32:
- err = __put_user(pos.mt_blkno, &((struct mtpos32 *)arg)->mt_blkno);
- break;
- case MTIOCGET32:
- err = __put_user(get.mt_type, &((struct mtget32 *)arg)->mt_type);
- err |= __put_user(get.mt_resid, &((struct mtget32 *)arg)->mt_resid);
- err |= __put_user(get.mt_dsreg, &((struct mtget32 *)arg)->mt_dsreg);
- err |= __put_user(get.mt_gstat, &((struct mtget32 *)arg)->mt_gstat);
- err |= __put_user(get.mt_erreg, &((struct mtget32 *)arg)->mt_erreg);
- err |= __put_user(get.mt_fileno, &((struct mtget32 *)arg)->mt_fileno);
- err |= __put_user(get.mt_blkno, &((struct mtget32 *)arg)->mt_blkno);
- break;
- case MTIOCGETCONFIG32:
- err = __put_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type);
- err |= __put_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type);
- err |= __put_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr);
- err |= __put_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr);
- err |= __put_user(info.port, &((struct mtconfiginfo32 *)arg)->port);
- err |= __put_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug);
- err |= __copy_to_user((char *)&((struct mtconfiginfo32 *)arg)->debug
- + sizeof(((struct mtconfiginfo32 *)arg)->debug),
- (char *)&info.debug + sizeof(info.debug), sizeof(__u32));
- break;
- case MTIOCSETCONFIG32:
- break;
- }
- return err ? -EFAULT: 0;
-}
-
-struct cdrom_read32 {
- int cdread_lba;
- compat_caddr_t cdread_bufaddr;
- int cdread_buflen;
-};
-
-struct cdrom_read_audio32 {
- union cdrom_addr addr;
- u_char addr_format;
- int nframes;
- compat_caddr_t buf;
-};
-
-struct cdrom_generic_command32 {
- unsigned char cmd[CDROM_PACKET_SIZE];
- compat_caddr_t buffer;
- unsigned int buflen;
- int stat;
- compat_caddr_t sense;
- compat_caddr_t reserved[3];
-};
-
-static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- struct cdrom_read cdread;
- struct cdrom_read_audio cdreadaudio;
- struct cdrom_generic_command cgc;
- compat_caddr_t addr;
- char *data = 0;
- void *karg;
- int err = 0;
-
- switch(cmd) {
- case CDROMREADMODE2:
- case CDROMREADMODE1:
- case CDROMREADRAW:
- case CDROMREADCOOKED:
- karg = &cdread;
- err = __get_user(cdread.cdread_lba, &((struct cdrom_read32 *)arg)->cdread_lba);
- err |= __get_user(addr, &((struct cdrom_read32 *)arg)->cdread_bufaddr);
- err |= __get_user(cdread.cdread_buflen, &((struct cdrom_read32 *)arg)->cdread_buflen);
- if (err)
- return -EFAULT;
- data = kmalloc(cdread.cdread_buflen, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
- cdread.cdread_bufaddr = data;
- break;
- case CDROMREADAUDIO:
- karg = &cdreadaudio;
- err = copy_from_user(&cdreadaudio.addr, &((struct cdrom_read_audio32 *)arg)->addr, sizeof(cdreadaudio.addr));
- err |= __get_user(cdreadaudio.addr_format, &((struct cdrom_read_audio32 *)arg)->addr_format);
- err |= __get_user(cdreadaudio.nframes, &((struct cdrom_read_audio32 *)arg)->nframes);
- err |= __get_user(addr, &((struct cdrom_read_audio32 *)arg)->buf);
- if (err)
- return -EFAULT;
- data = kmalloc(cdreadaudio.nframes * 2352, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
- cdreadaudio.buf = data;
- break;
- case CDROM_SEND_PACKET:
- karg = &cgc;
- err = copy_from_user(cgc.cmd, &((struct cdrom_generic_command32 *)arg)->cmd, sizeof(cgc.cmd));
- err |= __get_user(addr, &((struct cdrom_generic_command32 *)arg)->buffer);
- err |= __get_user(cgc.buflen, &((struct cdrom_generic_command32 *)arg)->buflen);
- if (err)
- return -EFAULT;
- if ((data = kmalloc(cgc.buflen, GFP_KERNEL)) == NULL)
- return -ENOMEM;
- cgc.buffer = data;
- break;
- default:
- do {
- static int count = 0;
- if (++count <= 20)
- printk("cdrom_ioctl: Unknown cmd fd(%d) "
- "cmd(%08x) arg(%08x)\n",
- (int)fd, (unsigned int)cmd, (unsigned int)arg);
- } while (0);
- return -EINVAL;
- }
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long)karg);
- set_fs (old_fs);
- if (err)
- goto out;
- switch (cmd) {
- case CDROMREADMODE2:
- case CDROMREADMODE1:
- case CDROMREADRAW:
- case CDROMREADCOOKED:
- err = copy_to_user((char *)A(addr), data, cdread.cdread_buflen);
- break;
- case CDROMREADAUDIO:
- err = copy_to_user((char *)A(addr), data, cdreadaudio.nframes * 2352);
- break;
- case CDROM_SEND_PACKET:
- err = copy_to_user((char *)A(addr), data, cgc.buflen);
- break;
- default:
- break;
- }
-out: if (data)
- kfree(data);
- return err ? -EFAULT : 0;
-}
-
-struct loop_info32 {
- int lo_number; /* ioctl r/o */
- compat_dev_t lo_device; /* ioctl r/o */
- unsigned int lo_inode; /* ioctl r/o */
- compat_dev_t lo_rdevice; /* ioctl r/o */
- int lo_offset;
- int lo_encrypt_type;
- int lo_encrypt_key_size; /* ioctl w/o */
- int lo_flags; /* ioctl r/o */
- char lo_name[LO_NAME_SIZE];
- unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
- unsigned int lo_init[2];
- char reserved[4];
-};
-
-static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- struct loop_info l;
- int err = -EINVAL;
-
- switch(cmd) {
- case LOOP_SET_STATUS:
- err = get_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);
- err |= __get_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
- err |= __get_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
- err |= __get_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
- err |= __copy_from_user((char *)&l.lo_offset, (char *)&((struct loop_info32 *)arg)->lo_offset,
- 8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
- if (err) {
- err = -EFAULT;
- } else {
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long)&l);
- set_fs (old_fs);
- }
- break;
- case LOOP_GET_STATUS:
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long)&l);
- set_fs (old_fs);
- if (!err) {
- err = put_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);
- err |= __put_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
- err |= __put_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
- err |= __put_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
- err |= __copy_to_user((char *)&((struct loop_info32 *)arg)->lo_offset,
- (char *)&l.lo_offset, (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
- if (err)
- err = -EFAULT;
- }
- break;
- default: {
- static int count = 0;
- if (++count <= 20)
- printk("%s: Unknown loop ioctl cmd, fd(%d) "
- "cmd(%08x) arg(%08lx)\n",
- __FUNCTION__, fd, cmd, arg);
- }
- }
- return err;
-}
-
-extern int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg);
-
-#ifdef CONFIG_VT
-static int vt_check(struct file *file)
-{
- struct tty_struct *tty;
- struct inode *inode = file->f_dentry->d_inode;
-
- if (file->f_op->ioctl != tty_ioctl)
- return -EINVAL;
-
- tty = (struct tty_struct *)file->private_data;
- if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl"))
- return -EINVAL;
-
- if (tty->driver->ioctl != vt_ioctl)
- return -EINVAL;
-
- /*
- * To have permissions to do most of the vt ioctls, we either have
- * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
- */
- if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
- return 1;
- return 0;
-}
-
-struct consolefontdesc32 {
- unsigned short charcount; /* characters in font (256 or 512) */
- unsigned short charheight; /* scan lines per character (1-32) */
- u32 chardata; /* font data in expanded form */
-};
-
-static int do_fontx_ioctl(unsigned int fd, int cmd, struct consolefontdesc32 *user_cfd, struct file *file)
-{
- struct consolefontdesc cfdarg;
- struct console_font_op op;
- int i, perm;
-
- perm = vt_check(file);
- if (perm < 0) return perm;
-
- if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc32)))
- return -EFAULT;
-
- cfdarg.chardata = (unsigned char *)A(((struct consolefontdesc32 *)&cfdarg)->chardata);
-
- switch (cmd) {
- case PIO_FONTX:
- if (!perm)
- return -EPERM;
- op.op = KD_FONT_OP_SET;
- op.flags = 0;
- op.width = 8;
- op.height = cfdarg.charheight;
- op.charcount = cfdarg.charcount;
- op.data = cfdarg.chardata;
- return con_font_op(fg_console, &op);
- case GIO_FONTX:
- if (!cfdarg.chardata)
- return 0;
- op.op = KD_FONT_OP_GET;
- op.flags = 0;
- op.width = 8;
- op.height = cfdarg.charheight;
- op.charcount = cfdarg.charcount;
- op.data = cfdarg.chardata;
- i = con_font_op(fg_console, &op);
- if (i)
- return i;
- cfdarg.charheight = op.height;
- cfdarg.charcount = op.charcount;
- ((struct consolefontdesc32 *)&cfdarg)->chardata = (unsigned long)cfdarg.chardata;
- if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc32)))
- return -EFAULT;
- return 0;
- }
- return -EINVAL;
-}
-
-struct console_font_op32 {
- unsigned int op; /* operation code KD_FONT_OP_* */
- unsigned int flags; /* KD_FONT_FLAG_* */
- unsigned int width, height; /* font size */
- unsigned int charcount;
- u32 data; /* font data with height fixed to 32 */
-};
-
-static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, struct console_font_op32 *fontop, struct file *file)
-{
- struct console_font_op op;
- int perm = vt_check(file), i;
- struct vt_struct *vt;
-
- if (perm < 0) return perm;
-
- if (copy_from_user(&op, (void *) fontop, sizeof(struct console_font_op32)))
- return -EFAULT;
- if (!perm && op.op != KD_FONT_OP_GET)
- return -EPERM;
- op.data = (unsigned char *)A(((struct console_font_op32 *)&op)->data);
- op.flags |= KD_FONT_FLAG_OLD;
- vt = (struct vt_struct *)((struct tty_struct *)file->private_data)->driver_data;
- i = con_font_op(vt->vc_num, &op);
- if (i) return i;
- ((struct console_font_op32 *)&op)->data = (unsigned long)op.data;
- if (copy_to_user((void *) fontop, &op, sizeof(struct console_font_op32)))
- return -EFAULT;
- return 0;
-}
-
-struct fb_fix_screeninfo32 {
- char id[16]; /* identification string eg "TT Builtin" */
- unsigned int smem_start; /* Start of frame buffer mem */
- /* (physical address) */
- __u32 smem_len; /* Length of frame buffer mem */
- __u32 type; /* see FB_TYPE_* */
- __u32 type_aux; /* Interleave for interleaved Planes */
- __u32 visual; /* see FB_VISUAL_* */
- __u16 xpanstep; /* zero if no hardware panning */
- __u16 ypanstep; /* zero if no hardware panning */
- __u16 ywrapstep; /* zero if no hardware ywrap */
- __u32 line_length; /* length of a line in bytes */
- unsigned int mmio_start; /* Start of Memory Mapped I/O */
- /* (physical address) */
- __u32 mmio_len; /* Length of Memory Mapped I/O */
- __u32 accel; /* Type of acceleration available */
- __u16 reserved[3]; /* Reserved for future compatibility */
-};
-
-static int do_fbioget_fscreeninfo_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- struct fb_fix_screeninfo fix;
- int err;
-
- set_fs(KERNEL_DS);
- err = sys_ioctl(fd, cmd, (long)&fix);
- set_fs(old_fs);
-
- if (err == 0) {
- unsigned int smem_start = fix.smem_start; /* lose top 32 bits */
- unsigned int mmio_start = fix.mmio_start; /* lose top 32 bits */
- int i;
-
- err = put_user(fix.id[0], &((struct fb_fix_screeninfo32 *)arg)->id[0]);
- for (i=1; i<16; i++) {
- err |= __put_user(fix.id[i], &((struct fb_fix_screeninfo32 *)arg)->id[i]);
- }
- err |= __put_user(smem_start, &((struct fb_fix_screeninfo32 *)arg)->smem_start);
- err |= __put_user(fix.smem_len, &((struct fb_fix_screeninfo32 *)arg)->smem_len);
- err |= __put_user(fix.type, &((struct fb_fix_screeninfo32 *)arg)->type);
- err |= __put_user(fix.type_aux, &((struct fb_fix_screeninfo32 *)arg)->type_aux);
- err |= __put_user(fix.visual, &((struct fb_fix_screeninfo32 *)arg)->visual);
- err |= __put_user(fix.xpanstep, &((struct fb_fix_screeninfo32 *)arg)->xpanstep);
- err |= __put_user(fix.ypanstep, &((struct fb_fix_screeninfo32 *)arg)->ypanstep);
- err |= __put_user(fix.ywrapstep, &((struct fb_fix_screeninfo32 *)arg)->ywrapstep);
- err |= __put_user(fix.line_length, &((struct fb_fix_screeninfo32 *)arg)->line_length);
- err |= __put_user(mmio_start, &((struct fb_fix_screeninfo32 *)arg)->mmio_start);
- err |= __put_user(fix.mmio_len, &((struct fb_fix_screeninfo32 *)arg)->mmio_len);
- err |= __put_user(fix.accel, &((struct fb_fix_screeninfo32 *)arg)->accel);
- err |= __put_user(fix.reserved[0], &((struct fb_fix_screeninfo32 *)arg)->reserved[0]);
- err |= __put_user(fix.reserved[1], &((struct fb_fix_screeninfo32 *)arg)->reserved[1]);
- err |= __put_user(fix.reserved[2], &((struct fb_fix_screeninfo32 *)arg)->reserved[2]);
- if (err)
- err = -EFAULT;
- }
- return err;
-}
-
-struct fb_cmap32 {
- __u32 start; /* First entry */
- __u32 len; /* Number of entries */
- __u32 redptr; /* Red values */
- __u32 greenptr;
- __u32 blueptr;
- __u32 transpptr; /* transparency, can be NULL */
-};
-
-static int do_fbiogetcmap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- struct fb_cmap cmap;
- int err;
-
- set_fs(KERNEL_DS);
- err = sys_ioctl(fd, cmd, (long)&cmap);
- set_fs(old_fs);
-
- if (err == 0) {
- __u32 redptr = (__u32)(__u64)cmap.red;
- __u32 greenptr = (__u32)(__u64)cmap.green;
- __u32 blueptr = (__u32)(__u64)cmap.blue;
- __u32 transpptr = (__u32)(__u64)cmap.transp;
-
- err = put_user(cmap.start, &((struct fb_cmap32 *)arg)->start);
- err |= __put_user(cmap.len, &((struct fb_cmap32 *)arg)->len);
- err |= __put_user(redptr, &((struct fb_cmap32 *)arg)->redptr);
- err |= __put_user(greenptr, &((struct fb_cmap32 *)arg)->greenptr);
- err |= __put_user(blueptr, &((struct fb_cmap32 *)arg)->blueptr);
- err |= __put_user(transpptr, &((struct fb_cmap32 *)arg)->transpptr);
- if (err)
- err = -EFAULT;
- }
- return err;
-}
-
-static int do_fbioputcmap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- struct fb_cmap cmap;
- __u32 redptr, greenptr, blueptr, transpptr;
- int err;
-
- err = get_user(cmap.start, &((struct fb_cmap32 *)arg)->start);
- err |= __get_user(cmap.len, &((struct fb_cmap32 *)arg)->len);
- err |= __get_user(redptr, &((struct fb_cmap32 *)arg)->redptr);
- err |= __get_user(greenptr, &((struct fb_cmap32 *)arg)->greenptr);
- err |= __get_user(blueptr, &((struct fb_cmap32 *)arg)->blueptr);
- err |= __get_user(transpptr, &((struct fb_cmap32 *)arg)->transpptr);
-
- if (err) {
- err = -EFAULT;
- } else {
- cmap.red = (__u16 *)(__u64)redptr;
- cmap.green = (__u16 *)(__u64)greenptr;
- cmap.blue = (__u16 *)(__u64)blueptr;
- cmap.transp = (__u16 *)(__u64)transpptr;
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long)&cmap);
- set_fs (old_fs);
- }
- return err;
-}
-
-struct unimapdesc32 {
- unsigned short entry_ct;
- u32 entries;
-};
-
-static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, struct unimapdesc32 *user_ud, struct file *file)
-{
- struct unimapdesc32 tmp;
- int perm = vt_check(file);
-
- if (perm < 0) return perm;
- if (copy_from_user(&tmp, user_ud, sizeof tmp))
- return -EFAULT;
- switch (cmd) {
- case PIO_UNIMAP:
- if (!perm) return -EPERM;
- return con_set_unimap(fg_console, tmp.entry_ct, (struct unipair *)A(tmp.entries));
- case GIO_UNIMAP:
- return con_get_unimap(fg_console, tmp.entry_ct, &(user_ud->entry_ct), (struct unipair *)A(tmp.entries));
- }
- return 0;
-}
-#endif /* CONFIG_VT */
-static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- __kernel_uid_t kuid;
- int err;
-
- cmd = SMB_IOC_GETMOUNTUID;
-
- set_fs(KERNEL_DS);
- err = sys_ioctl(fd, cmd, (unsigned long)&kuid);
- set_fs(old_fs);
-
- if (err >= 0)
- err = put_user(kuid, (compat_uid_t *)arg);
-
- return err;
-}
-
struct ncp_ioctl_request_32 {
unsigned int function;
unsigned int size;
@@ -2360,812 +356,6 @@
return err;
}
-struct atmif_sioc32 {
- int number;
- int length;
- compat_caddr_t arg;
-};
-
-struct atm_iobuf32 {
- int length;
- compat_caddr_t buffer;
-};
-
-#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32)
-#define ATM_GETNAMES32 _IOW('a', ATMIOC_ITF+3, struct atm_iobuf32)
-#define ATM_GETTYPE32 _IOW('a', ATMIOC_ITF+4, struct atmif_sioc32)
-#define ATM_GETESI32 _IOW('a', ATMIOC_ITF+5, struct atmif_sioc32)
-#define ATM_GETADDR32 _IOW('a', ATMIOC_ITF+6, struct atmif_sioc32)
-#define ATM_RSTADDR32 _IOW('a', ATMIOC_ITF+7, struct atmif_sioc32)
-#define ATM_ADDADDR32 _IOW('a', ATMIOC_ITF+8, struct atmif_sioc32)
-#define ATM_DELADDR32 _IOW('a', ATMIOC_ITF+9, struct atmif_sioc32)
-#define ATM_GETCIRANGE32 _IOW('a', ATMIOC_ITF+10, struct atmif_sioc32)
-#define ATM_SETCIRANGE32 _IOW('a', ATMIOC_ITF+11, struct atmif_sioc32)
-#define ATM_SETESI32 _IOW('a', ATMIOC_ITF+12, struct atmif_sioc32)
-#define ATM_SETESIF32 _IOW('a', ATMIOC_ITF+13, struct atmif_sioc32)
-#define ATM_GETSTAT32 _IOW('a', ATMIOC_SARCOM+0, struct atmif_sioc32)
-#define ATM_GETSTATZ32 _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32)
-#define ATM_GETLOOP32 _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32)
-#define ATM_SETLOOP32 _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32)
-#define ATM_QUERYLOOP32 _IOW('a', ATMIOC_SARCOM+4, struct atmif_sioc32)
-
-static struct {
- unsigned int cmd32;
- unsigned int cmd;
-} atm_ioctl_map[] = {
- { ATM_GETLINKRATE32, ATM_GETLINKRATE },
- { ATM_GETNAMES32, ATM_GETNAMES },
- { ATM_GETTYPE32, ATM_GETTYPE },
- { ATM_GETESI32, ATM_GETESI },
- { ATM_GETADDR32, ATM_GETADDR },
- { ATM_RSTADDR32, ATM_RSTADDR },
- { ATM_ADDADDR32, ATM_ADDADDR },
- { ATM_DELADDR32, ATM_DELADDR },
- { ATM_GETCIRANGE32, ATM_GETCIRANGE },
- { ATM_SETCIRANGE32, ATM_SETCIRANGE },
- { ATM_SETESI32, ATM_SETESI },
- { ATM_SETESIF32, ATM_SETESIF },
- { ATM_GETSTAT32, ATM_GETSTAT },
- { ATM_GETSTATZ32, ATM_GETSTATZ },
- { ATM_GETLOOP32, ATM_GETLOOP },
- { ATM_SETLOOP32, ATM_SETLOOP },
- { ATM_QUERYLOOP32, ATM_QUERYLOOP }
-};
-
-#define NR_ATM_IOCTL (sizeof(atm_ioctl_map)/sizeof(atm_ioctl_map[0]))
-
-
-static int do_atm_iobuf(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct atm_iobuf32 iobuf32;
- struct atm_iobuf iobuf = { 0, NULL };
- mm_segment_t old_fs;
- int err;
-
- err = copy_from_user(&iobuf32, (struct atm_iobuf32*)arg,
- sizeof(struct atm_iobuf32));
- if (err)
- return -EFAULT;
-
- iobuf.length = iobuf32.length;
-
- if (iobuf32.buffer == (compat_caddr_t) NULL || iobuf32.length == 0) {
- iobuf.buffer = (void*)(unsigned long)iobuf32.buffer;
- } else {
- iobuf.buffer = kmalloc(iobuf.length, GFP_KERNEL);
- if (iobuf.buffer == NULL) {
- err = -ENOMEM;
- goto out;
- }
-
- err = copy_from_user(iobuf.buffer, (void *)A(iobuf32.buffer), iobuf.length);
- if (err) {
- err = -EFAULT;
- goto out;
- }
- }
-
- old_fs = get_fs(); set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long)&iobuf);
- set_fs (old_fs);
- if (err)
- goto out;
-
- if (iobuf.buffer && iobuf.length > 0) {
- err = copy_to_user((void *)A(iobuf32.buffer), iobuf.buffer, iobuf.length);
- if (err) {
- err = -EFAULT;
- goto out;
- }
- }
- err = __put_user(iobuf.length, &(((struct atm_iobuf32*)arg)->length));
-
- out:
- if (iobuf32.buffer && iobuf32.length > 0)
- kfree(iobuf.buffer);
-
- return err;
-}
-
-
-static int do_atmif_sioc(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct atmif_sioc32 sioc32;
- struct atmif_sioc sioc = { 0, 0, NULL };
- mm_segment_t old_fs;
- int err;
-
- err = copy_from_user(&sioc32, (struct atmif_sioc32*)arg,
- sizeof(struct atmif_sioc32));
- if (err)
- return -EFAULT;
-
- sioc.number = sioc32.number;
- sioc.length = sioc32.length;
-
- if (sioc32.arg == (compat_caddr_t) NULL || sioc32.length == 0) {
- sioc.arg = (void*)(unsigned long)sioc32.arg;
- } else {
- sioc.arg = kmalloc(sioc.length, GFP_KERNEL);
- if (sioc.arg == NULL) {
- err = -ENOMEM;
- goto out;
- }
-
- err = copy_from_user(sioc.arg, (void *)A(sioc32.arg), sioc32.length);
- if (err) {
- err = -EFAULT;
- goto out;
- }
- }
-
- old_fs = get_fs(); set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long)&sioc);
- set_fs (old_fs);
- if (err) {
- goto out;
- }
-
- if (sioc.arg && sioc.length > 0) {
- err = copy_to_user((void *)A(sioc32.arg), sioc.arg, sioc.length);
- if (err) {
- err = -EFAULT;
- goto out;
- }
- }
- err = __put_user(sioc.length, &(((struct atmif_sioc32*)arg)->length));
-
- out:
- if (sioc32.arg && sioc32.length > 0)
- kfree(sioc.arg);
-
- return err;
-}
-
-
-static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg)
-{
- int i;
- unsigned int cmd = 0;
-
- switch (cmd32) {
- case SONET_GETSTAT:
- case SONET_GETSTATZ:
- case SONET_GETDIAG:
- case SONET_SETDIAG:
- case SONET_CLRDIAG:
- case SONET_SETFRAMING:
- case SONET_GETFRAMING:
- case SONET_GETFRSENSE:
- return do_atmif_sioc(fd, cmd32, arg);
- }
-
- for (i = 0; i < NR_ATM_IOCTL; i++) {
- if (cmd32 == atm_ioctl_map[i].cmd32) {
- cmd = atm_ioctl_map[i].cmd;
- break;
- }
- }
- if (i == NR_ATM_IOCTL) {
- return -EINVAL;
- }
-
- switch (cmd) {
- case ATM_GETNAMES:
- return do_atm_iobuf(fd, cmd, arg);
-
- case ATM_GETLINKRATE:
- case ATM_GETTYPE:
- case ATM_GETESI:
- case ATM_GETADDR:
- case ATM_RSTADDR:
- case ATM_ADDADDR:
- case ATM_DELADDR:
- case ATM_GETCIRANGE:
- case ATM_SETCIRANGE:
- case ATM_SETESI:
- case ATM_SETESIF:
- case ATM_GETSTAT:
- case ATM_GETSTATZ:
- case ATM_GETLOOP:
- case ATM_SETLOOP:
- case ATM_QUERYLOOP:
- return do_atmif_sioc(fd, cmd, arg);
- }
-
- return -EINVAL;
-}
-
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-/* This really belongs in include/linux/drm.h -DaveM */
-#include "../../../drivers/char/drm/drm.h"
-
-typedef struct drm32_version {
- int version_major; /* Major version */
- int version_minor; /* Minor version */
- int version_patchlevel;/* Patch level */
- int name_len; /* Length of name buffer */
- u32 name; /* Name of driver */
- int date_len; /* Length of date buffer */
- u32 date; /* User-space buffer to hold date */
- int desc_len; /* Length of desc buffer */
- u32 desc; /* User-space buffer to hold desc */
-} drm32_version_t;
-#define DRM32_IOCTL_VERSION DRM_IOWR(0x00, drm32_version_t)
-
-static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_version_t *uversion = (drm32_version_t *)arg;
- char *name_ptr, *date_ptr, *desc_ptr;
- u32 tmp1, tmp2, tmp3;
- drm_version_t kversion;
- mm_segment_t old_fs;
- int ret;
-
- memset(&kversion, 0, sizeof(kversion));
- if (get_user(kversion.name_len, &uversion->name_len) ||
- get_user(kversion.date_len, &uversion->date_len) ||
- get_user(kversion.desc_len, &uversion->desc_len) ||
- get_user(tmp1, &uversion->name) ||
- get_user(tmp2, &uversion->date) ||
- get_user(tmp3, &uversion->desc))
- return -EFAULT;
-
- name_ptr = (char *) A(tmp1);
- date_ptr = (char *) A(tmp2);
- desc_ptr = (char *) A(tmp3);
-
- ret = -ENOMEM;
- if (kversion.name_len && name_ptr) {
- kversion.name = kmalloc(kversion.name_len, GFP_KERNEL);
- if (!kversion.name)
- goto out;
- }
- if (kversion.date_len && date_ptr) {
- kversion.date = kmalloc(kversion.date_len, GFP_KERNEL);
- if (!kversion.date)
- goto out;
- }
- if (kversion.desc_len && desc_ptr) {
- kversion.desc = kmalloc(kversion.desc_len, GFP_KERNEL);
- if (!kversion.desc)
- goto out;
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl (fd, DRM_IOCTL_VERSION, (unsigned long)&kversion);
- set_fs(old_fs);
-
- if (!ret) {
- if ((kversion.name &&
- copy_to_user(name_ptr, kversion.name, kversion.name_len)) ||
- (kversion.date &&
- copy_to_user(date_ptr, kversion.date, kversion.date_len)) ||
- (kversion.desc &&
- copy_to_user(desc_ptr, kversion.desc, kversion.desc_len)))
- ret = -EFAULT;
- if (put_user(kversion.version_major, &uversion->version_major) ||
- put_user(kversion.version_minor, &uversion->version_minor) ||
- put_user(kversion.version_patchlevel, &uversion->version_patchlevel) ||
- put_user(kversion.name_len, &uversion->name_len) ||
- put_user(kversion.date_len, &uversion->date_len) ||
- put_user(kversion.desc_len, &uversion->desc_len))
- ret = -EFAULT;
- }
-
-out:
- if (kversion.name)
- kfree(kversion.name);
- if (kversion.date)
- kfree(kversion.date);
- if (kversion.desc)
- kfree(kversion.desc);
- return ret;
-}
-
-typedef struct drm32_unique {
- int unique_len; /* Length of unique */
- u32 unique; /* Unique name for driver instantiation */
-} drm32_unique_t;
-#define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t)
-#define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t)
-
-static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_unique_t *uarg = (drm32_unique_t *)arg;
- drm_unique_t karg;
- mm_segment_t old_fs;
- char *uptr;
- u32 tmp;
- int ret;
-
- if (get_user(karg.unique_len, &uarg->unique_len))
- return -EFAULT;
- karg.unique = NULL;
-
- if (get_user(tmp, &uarg->unique))
- return -EFAULT;
-
- uptr = (char *) A(tmp);
-
- if (uptr) {
- karg.unique = kmalloc(karg.unique_len, GFP_KERNEL);
- if (!karg.unique)
- return -ENOMEM;
- if (cmd == DRM32_IOCTL_SET_UNIQUE &&
- copy_from_user(karg.unique, uptr, karg.unique_len)) {
- kfree(karg.unique);
- return -EFAULT;
- }
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- if (cmd == DRM32_IOCTL_GET_UNIQUE)
- ret = sys_ioctl (fd, DRM_IOCTL_GET_UNIQUE, (unsigned long)&karg);
- else
- ret = sys_ioctl (fd, DRM_IOCTL_SET_UNIQUE, (unsigned long)&karg);
- set_fs(old_fs);
-
- if (!ret) {
- if (cmd == DRM32_IOCTL_GET_UNIQUE &&
- uptr != NULL &&
- copy_to_user(uptr, karg.unique, karg.unique_len))
- ret = -EFAULT;
- if (put_user(karg.unique_len, &uarg->unique_len))
- ret = -EFAULT;
- }
-
- if (karg.unique != NULL)
- kfree(karg.unique);
-
- return ret;
-}
-
-typedef struct drm32_map {
- u32 offset; /* Requested physical address (0 for SAREA)*/
- u32 size; /* Requested physical size (bytes) */
- drm_map_type_t type; /* Type of memory to map */
- drm_map_flags_t flags; /* Flags */
- u32 handle; /* User-space: "Handle" to pass to mmap */
- /* Kernel-space: kernel-virtual address */
- int mtrr; /* MTRR slot used */
- /* Private data */
-} drm32_map_t;
-#define DRM32_IOCTL_ADD_MAP DRM_IOWR(0x15, drm32_map_t)
-
-static int drm32_addmap(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_map_t *uarg = (drm32_map_t *) arg;
- drm_map_t karg;
- mm_segment_t old_fs;
- u32 tmp;
- int ret;
-
- ret = get_user(karg.offset, &uarg->offset);
- ret |= get_user(karg.size, &uarg->size);
- ret |= get_user(karg.type, &uarg->type);
- ret |= get_user(karg.flags, &uarg->flags);
- ret |= get_user(tmp, &uarg->handle);
- ret |= get_user(karg.mtrr, &uarg->mtrr);
- if (ret)
- return -EFAULT;
-
- karg.handle = (void *) A(tmp);
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_ADD_MAP, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- ret = put_user(karg.offset, &uarg->offset);
- ret |= put_user(karg.size, &uarg->size);
- ret |= put_user(karg.type, &uarg->type);
- ret |= put_user(karg.flags, &uarg->flags);
- tmp = (u32) (long)karg.handle;
- ret |= put_user(tmp, &uarg->handle);
- ret |= put_user(karg.mtrr, &uarg->mtrr);
- if (ret)
- ret = -EFAULT;
- }
-
- return ret;
-}
-
-typedef struct drm32_buf_info {
- int count; /* Entries in list */
- u32 list; /* (drm_buf_desc_t *) */
-} drm32_buf_info_t;
-#define DRM32_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm32_buf_info_t)
-
-static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_buf_info_t *uarg = (drm32_buf_info_t *)arg;
- drm_buf_desc_t *ulist;
- drm_buf_info_t karg;
- mm_segment_t old_fs;
- int orig_count, ret;
- u32 tmp;
-
- if (get_user(karg.count, &uarg->count) ||
- get_user(tmp, &uarg->list))
- return -EFAULT;
-
- ulist = (drm_buf_desc_t *) A(tmp);
-
- orig_count = karg.count;
-
- karg.list = kmalloc(karg.count * sizeof(drm_buf_desc_t), GFP_KERNEL);
- if (!karg.list)
- return -EFAULT;
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_INFO_BUFS, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- if (karg.count <= orig_count &&
- (copy_to_user(ulist, karg.list,
- karg.count * sizeof(drm_buf_desc_t))))
- ret = -EFAULT;
- if (put_user(karg.count, &uarg->count))
- ret = -EFAULT;
- }
-
- kfree(karg.list);
-
- return ret;
-}
-
-typedef struct drm32_buf_free {
- int count;
- u32 list; /* (int *) */
-} drm32_buf_free_t;
-#define DRM32_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm32_buf_free_t)
-
-static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_buf_free_t *uarg = (drm32_buf_free_t *)arg;
- drm_buf_free_t karg;
- mm_segment_t old_fs;
- int *ulist;
- int ret;
- u32 tmp;
-
- if (get_user(karg.count, &uarg->count) ||
- get_user(tmp, &uarg->list))
- return -EFAULT;
-
- ulist = (int *) A(tmp);
-
- karg.list = kmalloc(karg.count * sizeof(int), GFP_KERNEL);
- if (!karg.list)
- return -ENOMEM;
-
- ret = -EFAULT;
- if (copy_from_user(karg.list, ulist, (karg.count * sizeof(int))))
- goto out;
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_FREE_BUFS, (unsigned long) &karg);
- set_fs(old_fs);
-
-out:
- kfree(karg.list);
-
- return ret;
-}
-
-typedef struct drm32_buf_pub {
- int idx; /* Index into master buflist */
- int total; /* Buffer size */
- int used; /* Amount of buffer in use (for DMA) */
- u32 address; /* Address of buffer (void *) */
-} drm32_buf_pub_t;
-
-typedef struct drm32_buf_map {
- int count; /* Length of buflist */
- u32 virtual; /* Mmaped area in user-virtual (void *) */
- u32 list; /* Buffer information (drm_buf_pub_t *) */
-} drm32_buf_map_t;
-#define DRM32_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm32_buf_map_t)
-
-static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_buf_map_t *uarg = (drm32_buf_map_t *)arg;
- drm32_buf_pub_t *ulist;
- drm_buf_map_t karg;
- mm_segment_t old_fs;
- int orig_count, ret, i;
- u32 tmp1, tmp2;
-
- if (get_user(karg.count, &uarg->count) ||
- get_user(tmp1, &uarg->virtual) ||
- get_user(tmp2, &uarg->list))
- return -EFAULT;
-
- karg.virtual = (void *) A(tmp1);
- ulist = (drm32_buf_pub_t *) A(tmp2);
-
- orig_count = karg.count;
-
- karg.list = kmalloc(karg.count * sizeof(drm_buf_pub_t), GFP_KERNEL);
- if (!karg.list)
- return -ENOMEM;
-
- ret = -EFAULT;
- for (i = 0; i < karg.count; i++) {
- if (get_user(karg.list[i].idx, &ulist[i].idx) ||
- get_user(karg.list[i].total, &ulist[i].total) ||
- get_user(karg.list[i].used, &ulist[i].used) ||
- get_user(tmp1, &ulist[i].address))
- goto out;
-
- karg.list[i].address = (void *) A(tmp1);
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_MAP_BUFS, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- for (i = 0; i < orig_count; i++) {
- tmp1 = (u32) (long) karg.list[i].address;
- if (put_user(karg.list[i].idx, &ulist[i].idx) ||
- put_user(karg.list[i].total, &ulist[i].total) ||
- put_user(karg.list[i].used, &ulist[i].used) ||
- put_user(tmp1, &ulist[i].address)) {
- ret = -EFAULT;
- goto out;
- }
- }
- if (put_user(karg.count, &uarg->count))
- ret = -EFAULT;
- }
-
-out:
- kfree(karg.list);
- return ret;
-}
-
-typedef struct drm32_dma {
- /* Indices here refer to the offset into
- buflist in drm_buf_get_t. */
- int context; /* Context handle */
- int send_count; /* Number of buffers to send */
- u32 send_indices; /* List of handles to buffers (int *) */
- u32 send_sizes; /* Lengths of data to send (int *) */
- drm_dma_flags_t flags; /* Flags */
- int request_count; /* Number of buffers requested */
- int request_size; /* Desired size for buffers */
- u32 request_indices; /* Buffer information (int *) */
- u32 request_sizes; /* (int *) */
- int granted_count; /* Number of buffers granted */
-} drm32_dma_t;
-#define DRM32_IOCTL_DMA DRM_IOWR(0x29, drm32_dma_t)
-
-/* RED PEN The DRM layer blindly dereferences the send/request
- * indice/size arrays even though they are userland
- * pointers. -DaveM
- */
-static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_dma_t *uarg = (drm32_dma_t *) arg;
- int *u_si, *u_ss, *u_ri, *u_rs;
- drm_dma_t karg;
- mm_segment_t old_fs;
- int ret;
- u32 tmp1, tmp2, tmp3, tmp4;
-
- karg.send_indices = karg.send_sizes = NULL;
- karg.request_indices = karg.request_sizes = NULL;
-
- if (get_user(karg.context, &uarg->context) ||
- get_user(karg.send_count, &uarg->send_count) ||
- get_user(tmp1, &uarg->send_indices) ||
- get_user(tmp2, &uarg->send_sizes) ||
- get_user(karg.flags, &uarg->flags) ||
- get_user(karg.request_count, &uarg->request_count) ||
- get_user(karg.request_size, &uarg->request_size) ||
- get_user(tmp3, &uarg->request_indices) ||
- get_user(tmp4, &uarg->request_sizes) ||
- get_user(karg.granted_count, &uarg->granted_count))
- return -EFAULT;
-
- u_si = (int *) A(tmp1);
- u_ss = (int *) A(tmp2);
- u_ri = (int *) A(tmp3);
- u_rs = (int *) A(tmp4);
-
- if (karg.send_count) {
- karg.send_indices = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
- karg.send_sizes = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
-
- ret = -ENOMEM;
- if (!karg.send_indices || !karg.send_sizes)
- goto out;
-
- ret = -EFAULT;
- if (copy_from_user(karg.send_indices, u_si,
- (karg.send_count * sizeof(int))) ||
- copy_from_user(karg.send_sizes, u_ss,
- (karg.send_count * sizeof(int))))
- goto out;
- }
-
- if (karg.request_count) {
- karg.request_indices = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
- karg.request_sizes = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
-
- ret = -ENOMEM;
- if (!karg.request_indices || !karg.request_sizes)
- goto out;
-
- ret = -EFAULT;
- if (copy_from_user(karg.request_indices, u_ri,
- (karg.request_count * sizeof(int))) ||
- copy_from_user(karg.request_sizes, u_rs,
- (karg.request_count * sizeof(int))))
- goto out;
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_DMA, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- if (put_user(karg.context, &uarg->context) ||
- put_user(karg.send_count, &uarg->send_count) ||
- put_user(karg.flags, &uarg->flags) ||
- put_user(karg.request_count, &uarg->request_count) ||
- put_user(karg.request_size, &uarg->request_size) ||
- put_user(karg.granted_count, &uarg->granted_count))
- ret = -EFAULT;
-
- if (karg.send_count) {
- if (copy_to_user(u_si, karg.send_indices,
- (karg.send_count * sizeof(int))) ||
- copy_to_user(u_ss, karg.send_sizes,
- (karg.send_count * sizeof(int))))
- ret = -EFAULT;
- }
- if (karg.request_count) {
- if (copy_to_user(u_ri, karg.request_indices,
- (karg.request_count * sizeof(int))) ||
- copy_to_user(u_rs, karg.request_sizes,
- (karg.request_count * sizeof(int))))
- ret = -EFAULT;
- }
- }
-
-out:
- if (karg.send_indices)
- kfree(karg.send_indices);
- if (karg.send_sizes)
- kfree(karg.send_sizes);
- if (karg.request_indices)
- kfree(karg.request_indices);
- if (karg.request_sizes)
- kfree(karg.request_sizes);
-
- return ret;
-}
-
-typedef struct drm32_ctx_res {
- int count;
- u32 contexts; /* (drm_ctx_t *) */
-} drm32_ctx_res_t;
-#define DRM32_IOCTL_RES_CTX DRM_IOWR(0x26, drm32_ctx_res_t)
-
-static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_ctx_res_t *uarg = (drm32_ctx_res_t *) arg;
- drm_ctx_t *ulist;
- drm_ctx_res_t karg;
- mm_segment_t old_fs;
- int orig_count, ret;
- u32 tmp;
-
- karg.contexts = NULL;
- if (get_user(karg.count, &uarg->count) ||
- get_user(tmp, &uarg->contexts))
- return -EFAULT;
-
- ulist = (drm_ctx_t *) A(tmp);
-
- orig_count = karg.count;
- if (karg.count && ulist) {
- karg.contexts = kmalloc((karg.count * sizeof(drm_ctx_t)), GFP_KERNEL);
- if (!karg.contexts)
- return -ENOMEM;
- if (copy_from_user(karg.contexts, ulist,
- (karg.count * sizeof(drm_ctx_t)))) {
- kfree(karg.contexts);
- return -EFAULT;
- }
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_RES_CTX, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- if (orig_count) {
- if (copy_to_user(ulist, karg.contexts,
- (orig_count * sizeof(drm_ctx_t))))
- ret = -EFAULT;
- }
- if (put_user(karg.count, &uarg->count))
- ret = -EFAULT;
- }
-
- if (karg.contexts)
- kfree(karg.contexts);
-
- return ret;
-}
-
-#endif
-
-static int ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- return -EINVAL;
-}
-
-static int broken_blkgetsize(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- /* The mkswap binary hard codes it to Intel value :-((( */
- return w_long(fd, BLKGETSIZE, arg);
-}
-
-struct blkpg_ioctl_arg32 {
- int op;
- int flags;
- int datalen;
- u32 data;
-};
-
-static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, struct blkpg_ioctl_arg32 *arg)
-{
- struct blkpg_ioctl_arg a;
- struct blkpg_partition p;
- int err;
- mm_segment_t old_fs = get_fs();
-
- err = get_user(a.op, &arg->op);
- err |= __get_user(a.flags, &arg->flags);
- err |= __get_user(a.datalen, &arg->datalen);
- err |= __get_user((long)a.data, &arg->data);
- if (err) return err;
- switch (a.op) {
- case BLKPG_ADD_PARTITION:
- case BLKPG_DEL_PARTITION:
- if (a.datalen < sizeof(struct blkpg_partition))
- return -EINVAL;
- if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition)))
- return -EFAULT;
- a.data = &p;
- set_fs (KERNEL_DS);
- err = sys_ioctl(fd, cmd, (unsigned long)&a);
- set_fs (old_fs);
- default:
- return -EINVAL;
- }
- return err;
-}
-
-static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg);
-}
-
struct usbdevfs_ctrltransfer32 {
__u8 bRequestType;
__u8 bRequest;
@@ -3557,867 +747,34 @@
return err;
}
-struct mtd_oob_buf32 {
- u32 start;
- u32 length;
- u32 ptr; /* unsigned char* */
-};
-
-#define MEMWRITEOOB32 _IOWR('M',3,struct mtd_oob_buf32)
-#define MEMREADOOB32 _IOWR('M',4,struct mtd_oob_buf32)
-
-static inline int
-mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- struct mtd_oob_buf32 *uarg = (struct mtd_oob_buf32 *)arg;
- struct mtd_oob_buf karg;
- u32 tmp;
- char *ptr;
- int ret;
-
- if (get_user(karg.start, &uarg->start) ||
- get_user(karg.length, &uarg->length) ||
- get_user(tmp, &uarg->ptr))
- return -EFAULT;
-
- ptr = (char *)A(tmp);
- if (0 >= karg.length)
- return -EINVAL;
-
- karg.ptr = kmalloc(karg.length, GFP_KERNEL);
- if (NULL == karg.ptr)
- return -ENOMEM;
-
- if (copy_from_user(karg.ptr, ptr, karg.length)) {
- kfree(karg.ptr);
- return -EFAULT;
- }
-
- set_fs(KERNEL_DS);
- if (MEMREADOOB32 == cmd)
- ret = sys_ioctl(fd, MEMREADOOB, (unsigned long)&karg);
- else if (MEMWRITEOOB32 == cmd)
- ret = sys_ioctl(fd, MEMWRITEOOB, (unsigned long)&karg);
- else
- ret = -EINVAL;
- set_fs(old_fs);
-
- if (0 == ret && cmd == MEMREADOOB32) {
- ret = copy_to_user(ptr, karg.ptr, karg.length);
- ret |= put_user(karg.start, &uarg->start);
- ret |= put_user(karg.length, &uarg->length);
- }
-
- kfree(karg.ptr);
- return ((0 == ret) ? 0 : -EFAULT);
-}
-
-/* Fix sizeof(sizeof()) breakage */
-#define BLKBSZGET_32 _IOR(0x12,112,int)
-#define BLKBSZSET_32 _IOW(0x12,113,int)
-#define BLKGETSIZE64_32 _IOR(0x12,114,int)
-
-static int do_blkbszget(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- return sys_ioctl(fd, BLKBSZGET, arg);
-}
-
-static int do_blkbszset(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- return sys_ioctl(fd, BLKBSZSET, arg);
-}
-
-static int do_blkgetsize64(unsigned int fd, unsigned int cmd,
- unsigned long arg)
-{
- return sys_ioctl(fd, BLKGETSIZE64, arg);
-}
-
-/* Bluetooth ioctls */
-#define HCIUARTSETPROTO _IOW('U', 200, int)
-#define HCIUARTGETPROTO _IOR('U', 201, int)
-
-#define BNEPCONNADD _IOW('B', 200, int)
-#define BNEPCONNDEL _IOW('B', 201, int)
-#define BNEPGETCONNLIST _IOR('B', 210, int)
-#define BNEPGETCONNINFO _IOR('B', 211, int)
-
-struct ioctl_trans {
- unsigned long cmd;
- unsigned long handler;
- unsigned long next;
-};
-
-#define COMPATIBLE_IOCTL(cmd) { cmd, (unsigned long)sys_ioctl, 0 },
+#define HANDLE_IOCTL(cmd,handler) { cmd, (ioctl_trans_handler_t)handler, 0 },
+#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl)
-#define HANDLE_IOCTL(cmd,handler) { cmd, (unsigned long)handler, 0 },
-
-#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
-#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t)
-
-static struct ioctl_trans ioctl_translations[] = {
- /* List here explicitly which ioctl's need translation,
- * all others default to calling sys_ioctl().
- */
-/* Big T */
-COMPATIBLE_IOCTL(TCGETA)
-COMPATIBLE_IOCTL(TCSETA)
-COMPATIBLE_IOCTL(TCSETAW)
-COMPATIBLE_IOCTL(TCSETAF)
-COMPATIBLE_IOCTL(TCSBRK)
+#define IOCTL_TABLE_START \
+ struct ioctl_trans ioctl_start[] = {
+#define IOCTL_TABLE_END \
+ }; struct ioctl_trans ioctl_end[0];
+
+IOCTL_TABLE_START
+#include <linux/compat_ioctl.h>
+#define DECLARES
+#include "compat_ioctl.c"
COMPATIBLE_IOCTL(TCSBRKP)
-COMPATIBLE_IOCTL(TCXONC)
-COMPATIBLE_IOCTL(TCFLSH)
-COMPATIBLE_IOCTL(TCGETS)
-COMPATIBLE_IOCTL(TCSETS)
-COMPATIBLE_IOCTL(TCSETSW)
-COMPATIBLE_IOCTL(TCSETSF)
-COMPATIBLE_IOCTL(TIOCLINUX)
COMPATIBLE_IOCTL(TIOCSTART)
COMPATIBLE_IOCTL(TIOCSTOP)
-/* Little t */
-COMPATIBLE_IOCTL(TIOCGETD)
-COMPATIBLE_IOCTL(TIOCSETD)
-COMPATIBLE_IOCTL(TIOCEXCL)
-COMPATIBLE_IOCTL(TIOCNXCL)
-COMPATIBLE_IOCTL(TIOCCONS)
-COMPATIBLE_IOCTL(TIOCGSOFTCAR)
-COMPATIBLE_IOCTL(TIOCSSOFTCAR)
-COMPATIBLE_IOCTL(TIOCSWINSZ)
-COMPATIBLE_IOCTL(TIOCGWINSZ)
-COMPATIBLE_IOCTL(TIOCMGET)
-COMPATIBLE_IOCTL(TIOCMBIC)
-COMPATIBLE_IOCTL(TIOCMBIS)
-COMPATIBLE_IOCTL(TIOCMSET)
-COMPATIBLE_IOCTL(TIOCPKT)
-COMPATIBLE_IOCTL(TIOCNOTTY)
-COMPATIBLE_IOCTL(TIOCSTI)
-COMPATIBLE_IOCTL(TIOCOUTQ)
-COMPATIBLE_IOCTL(TIOCSPGRP)
-COMPATIBLE_IOCTL(TIOCGPGRP)
-COMPATIBLE_IOCTL(TIOCSCTTY)
-COMPATIBLE_IOCTL(TIOCGPTN)
-COMPATIBLE_IOCTL(TIOCSPTLCK)
COMPATIBLE_IOCTL(TIOCGSERIAL)
COMPATIBLE_IOCTL(TIOCSSERIAL)
-COMPATIBLE_IOCTL(TIOCSERGETLSR)
COMPATIBLE_IOCTL(TIOCSLTC)
-/* Big F */
-COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO)
-COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO)
-COMPATIBLE_IOCTL(FBIOPAN_DISPLAY)
-COMPATIBLE_IOCTL(FBIOGET_CON2FBMAP)
-COMPATIBLE_IOCTL(FBIOPUT_CON2FBMAP)
#if 0
COMPATIBLE_IOCTL(FBIOBLANK)
#endif
-/* Little f */
-COMPATIBLE_IOCTL(FIOCLEX)
-COMPATIBLE_IOCTL(FIONCLEX)
-COMPATIBLE_IOCTL(FIOASYNC)
-COMPATIBLE_IOCTL(FIONBIO)
-COMPATIBLE_IOCTL(FIONREAD) /* This is also TIOCINQ */
-/* 0x00 */
-COMPATIBLE_IOCTL(FIBMAP)
-COMPATIBLE_IOCTL(FIGETBSZ)
-/* 0x03 -- HD/IDE ioctl's used by hdparm and friends.
- * Some need translations, these do not.
- */
-COMPATIBLE_IOCTL(HDIO_GET_IDENTITY)
-COMPATIBLE_IOCTL(HDIO_SET_DMA)
-COMPATIBLE_IOCTL(HDIO_SET_UNMASKINTR)
-COMPATIBLE_IOCTL(HDIO_SET_NOWERR)
-COMPATIBLE_IOCTL(HDIO_SET_32BIT)
-COMPATIBLE_IOCTL(HDIO_SET_MULTCOUNT)
-COMPATIBLE_IOCTL(HDIO_DRIVE_CMD)
-COMPATIBLE_IOCTL(HDIO_SET_PIO_MODE)
-COMPATIBLE_IOCTL(HDIO_SET_NICE)
-/* 0x02 -- Floppy ioctls */
-COMPATIBLE_IOCTL(FDMSGON)
-COMPATIBLE_IOCTL(FDMSGOFF)
-COMPATIBLE_IOCTL(FDSETEMSGTRESH)
-COMPATIBLE_IOCTL(FDFLUSH)
-COMPATIBLE_IOCTL(FDWERRORCLR)
-COMPATIBLE_IOCTL(FDSETMAXERRS)
-COMPATIBLE_IOCTL(FDGETMAXERRS)
-COMPATIBLE_IOCTL(FDGETDRVTYP)
-COMPATIBLE_IOCTL(FDEJECT)
-COMPATIBLE_IOCTL(FDCLRPRM)
-COMPATIBLE_IOCTL(FDFMTBEG)
-COMPATIBLE_IOCTL(FDFMTEND)
-COMPATIBLE_IOCTL(FDRESET)
-COMPATIBLE_IOCTL(FDTWADDLE)
-COMPATIBLE_IOCTL(FDFMTTRK)
-COMPATIBLE_IOCTL(FDRAWCMD)
-/* 0x12 */
-COMPATIBLE_IOCTL(BLKROSET)
-COMPATIBLE_IOCTL(BLKROGET)
-COMPATIBLE_IOCTL(BLKRRPART)
-COMPATIBLE_IOCTL(BLKFLSBUF)
-COMPATIBLE_IOCTL(BLKSECTSET)
-COMPATIBLE_IOCTL(BLKSSZGET)
-COMPATIBLE_IOCTL(BLKRASET)
-COMPATIBLE_IOCTL(BLKFRASET)
-/* RAID */
-COMPATIBLE_IOCTL(RAID_VERSION)
-COMPATIBLE_IOCTL(GET_ARRAY_INFO)
-COMPATIBLE_IOCTL(GET_DISK_INFO)
-COMPATIBLE_IOCTL(PRINT_RAID_DEBUG)
-COMPATIBLE_IOCTL(CLEAR_ARRAY)
-COMPATIBLE_IOCTL(ADD_NEW_DISK)
-COMPATIBLE_IOCTL(HOT_REMOVE_DISK)
-COMPATIBLE_IOCTL(SET_ARRAY_INFO)
-COMPATIBLE_IOCTL(SET_DISK_INFO)
-COMPATIBLE_IOCTL(WRITE_RAID_INFO)
-COMPATIBLE_IOCTL(UNPROTECT_ARRAY)
-COMPATIBLE_IOCTL(PROTECT_ARRAY)
-COMPATIBLE_IOCTL(HOT_ADD_DISK)
-COMPATIBLE_IOCTL(SET_DISK_FAULTY)
-COMPATIBLE_IOCTL(RUN_ARRAY)
-COMPATIBLE_IOCTL(START_ARRAY)
-COMPATIBLE_IOCTL(STOP_ARRAY)
-COMPATIBLE_IOCTL(STOP_ARRAY_RO)
-COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
-/* Big K */
-COMPATIBLE_IOCTL(PIO_FONT)
-COMPATIBLE_IOCTL(GIO_FONT)
-COMPATIBLE_IOCTL(KDSIGACCEPT)
-COMPATIBLE_IOCTL(KDGETKEYCODE)
-COMPATIBLE_IOCTL(KDSETKEYCODE)
-COMPATIBLE_IOCTL(KIOCSOUND)
-COMPATIBLE_IOCTL(KDMKTONE)
-COMPATIBLE_IOCTL(KDGKBTYPE)
-COMPATIBLE_IOCTL(KDSETMODE)
-COMPATIBLE_IOCTL(KDGETMODE)
-COMPATIBLE_IOCTL(KDSKBMODE)
-COMPATIBLE_IOCTL(KDGKBMODE)
-COMPATIBLE_IOCTL(KDSKBMETA)
-COMPATIBLE_IOCTL(KDGKBMETA)
-COMPATIBLE_IOCTL(KDGKBENT)
-COMPATIBLE_IOCTL(KDSKBENT)
-COMPATIBLE_IOCTL(KDGKBSENT)
-COMPATIBLE_IOCTL(KDSKBSENT)
-COMPATIBLE_IOCTL(KDGKBDIACR)
-COMPATIBLE_IOCTL(KDKBDREP)
-COMPATIBLE_IOCTL(KDSKBDIACR)
-COMPATIBLE_IOCTL(KDGKBLED)
-COMPATIBLE_IOCTL(KDSKBLED)
-COMPATIBLE_IOCTL(KDGETLED)
-COMPATIBLE_IOCTL(KDSETLED)
-COMPATIBLE_IOCTL(GIO_SCRNMAP)
-COMPATIBLE_IOCTL(PIO_SCRNMAP)
-COMPATIBLE_IOCTL(GIO_UNISCRNMAP)
-COMPATIBLE_IOCTL(PIO_UNISCRNMAP)
-COMPATIBLE_IOCTL(PIO_FONTRESET)
-COMPATIBLE_IOCTL(PIO_UNIMAPCLR)
-/* Big S */
-COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN)
-COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST)
-COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI)
-COMPATIBLE_IOCTL(SCSI_IOCTL_DOORLOCK)
-COMPATIBLE_IOCTL(SCSI_IOCTL_DOORUNLOCK)
-COMPATIBLE_IOCTL(SCSI_IOCTL_TEST_UNIT_READY)
-COMPATIBLE_IOCTL(SCSI_IOCTL_TAGGED_ENABLE)
-COMPATIBLE_IOCTL(SCSI_IOCTL_TAGGED_DISABLE)
-COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER)
-COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND)
-/* Big T */
-COMPATIBLE_IOCTL(TUNSETNOCSUM)
-COMPATIBLE_IOCTL(TUNSETDEBUG)
-COMPATIBLE_IOCTL(TUNSETIFF)
-COMPATIBLE_IOCTL(TUNSETPERSIST)
-COMPATIBLE_IOCTL(TUNSETOWNER)
-/* Big V */
-COMPATIBLE_IOCTL(VT_SETMODE)
-COMPATIBLE_IOCTL(VT_GETMODE)
-COMPATIBLE_IOCTL(VT_GETSTATE)
-COMPATIBLE_IOCTL(VT_OPENQRY)
-COMPATIBLE_IOCTL(VT_ACTIVATE)
-COMPATIBLE_IOCTL(VT_WAITACTIVE)
-COMPATIBLE_IOCTL(VT_RELDISP)
-COMPATIBLE_IOCTL(VT_DISALLOCATE)
-COMPATIBLE_IOCTL(VT_RESIZE)
-COMPATIBLE_IOCTL(VT_RESIZEX)
-COMPATIBLE_IOCTL(VT_LOCKSWITCH)
-COMPATIBLE_IOCTL(VT_UNLOCKSWITCH)
-/* Little v, the video4linux ioctls */
-COMPATIBLE_IOCTL(VIDIOCGCAP)
-COMPATIBLE_IOCTL(VIDIOCGCHAN)
-COMPATIBLE_IOCTL(VIDIOCSCHAN)
-COMPATIBLE_IOCTL(VIDIOCGPICT)
-COMPATIBLE_IOCTL(VIDIOCSPICT)
-COMPATIBLE_IOCTL(VIDIOCCAPTURE)
-COMPATIBLE_IOCTL(VIDIOCKEY)
-COMPATIBLE_IOCTL(VIDIOCGAUDIO)
-COMPATIBLE_IOCTL(VIDIOCSAUDIO)
-COMPATIBLE_IOCTL(VIDIOCSYNC)
-COMPATIBLE_IOCTL(VIDIOCMCAPTURE)
-COMPATIBLE_IOCTL(VIDIOCGMBUF)
-COMPATIBLE_IOCTL(VIDIOCGUNIT)
-COMPATIBLE_IOCTL(VIDIOCGCAPTURE)
-COMPATIBLE_IOCTL(VIDIOCSCAPTURE)
-/* BTTV specific... */
-COMPATIBLE_IOCTL(_IOW('v', BASE_VIDIOCPRIVATE+0, char [256]))
-COMPATIBLE_IOCTL(_IOR('v', BASE_VIDIOCPRIVATE+1, char [256]))
-COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int))
-COMPATIBLE_IOCTL(_IOW('v' , BASE_VIDIOCPRIVATE+3, char [16])) /* struct bttv_pll_info */
-COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+4, int))
-COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+5, int))
-COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+6, int))
-COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+7, int))
/* Little p (/dev/rtc, /dev/envctrl, etc.) */
COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
-COMPATIBLE_IOCTL(RTC_AIE_ON)
-COMPATIBLE_IOCTL(RTC_AIE_OFF)
-COMPATIBLE_IOCTL(RTC_UIE_ON)
-COMPATIBLE_IOCTL(RTC_UIE_OFF)
-COMPATIBLE_IOCTL(RTC_PIE_ON)
-COMPATIBLE_IOCTL(RTC_PIE_OFF)
-COMPATIBLE_IOCTL(RTC_WIE_ON)
-COMPATIBLE_IOCTL(RTC_WIE_OFF)
-COMPATIBLE_IOCTL(RTC_ALM_SET)
-COMPATIBLE_IOCTL(RTC_ALM_READ)
-COMPATIBLE_IOCTL(RTC_RD_TIME)
-COMPATIBLE_IOCTL(RTC_SET_TIME)
-COMPATIBLE_IOCTL(RTC_WKALM_SET)
-COMPATIBLE_IOCTL(RTC_WKALM_RD)
-/* Little m */
-COMPATIBLE_IOCTL(MTIOCTOP)
-/* Socket level stuff */
-COMPATIBLE_IOCTL(FIOSETOWN)
-COMPATIBLE_IOCTL(SIOCSPGRP)
-COMPATIBLE_IOCTL(FIOGETOWN)
-COMPATIBLE_IOCTL(SIOCGPGRP)
-COMPATIBLE_IOCTL(SIOCATMARK)
-COMPATIBLE_IOCTL(SIOCSIFLINK)
-COMPATIBLE_IOCTL(SIOCSIFENCAP)
-COMPATIBLE_IOCTL(SIOCGIFENCAP)
-COMPATIBLE_IOCTL(SIOCSIFBR)
-COMPATIBLE_IOCTL(SIOCGIFBR)
-COMPATIBLE_IOCTL(SIOCSARP)
-COMPATIBLE_IOCTL(SIOCGARP)
-COMPATIBLE_IOCTL(SIOCDARP)
-COMPATIBLE_IOCTL(SIOCSRARP)
-COMPATIBLE_IOCTL(SIOCGRARP)
-COMPATIBLE_IOCTL(SIOCDRARP)
-COMPATIBLE_IOCTL(SIOCADDDLCI)
-COMPATIBLE_IOCTL(SIOCDELDLCI)
-COMPATIBLE_IOCTL(SIOCGMIIPHY)
-COMPATIBLE_IOCTL(SIOCGMIIREG)
-COMPATIBLE_IOCTL(SIOCSMIIREG)
-COMPATIBLE_IOCTL(SIOCGIFVLAN)
-COMPATIBLE_IOCTL(SIOCSIFVLAN)
-/* SG stuff */
-COMPATIBLE_IOCTL(SG_SET_TIMEOUT)
-COMPATIBLE_IOCTL(SG_GET_TIMEOUT)
-COMPATIBLE_IOCTL(SG_EMULATED_HOST)
-COMPATIBLE_IOCTL(SG_SET_TRANSFORM)
-COMPATIBLE_IOCTL(SG_GET_TRANSFORM)
-COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE)
-COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE)
-COMPATIBLE_IOCTL(SG_GET_SCSI_ID)
-COMPATIBLE_IOCTL(SG_SET_FORCE_LOW_DMA)
-COMPATIBLE_IOCTL(SG_GET_LOW_DMA)
-COMPATIBLE_IOCTL(SG_SET_FORCE_PACK_ID)
-COMPATIBLE_IOCTL(SG_GET_PACK_ID)
-COMPATIBLE_IOCTL(SG_GET_NUM_WAITING)
-COMPATIBLE_IOCTL(SG_SET_DEBUG)
-COMPATIBLE_IOCTL(SG_GET_SG_TABLESIZE)
-COMPATIBLE_IOCTL(SG_GET_COMMAND_Q)
-COMPATIBLE_IOCTL(SG_SET_COMMAND_Q)
-COMPATIBLE_IOCTL(SG_GET_VERSION_NUM)
-COMPATIBLE_IOCTL(SG_NEXT_CMD_LEN)
-COMPATIBLE_IOCTL(SG_SCSI_RESET)
-COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE)
-COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN)
-COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN)
-/* PPP stuff */
-COMPATIBLE_IOCTL(PPPIOCGFLAGS)
-COMPATIBLE_IOCTL(PPPIOCSFLAGS)
-COMPATIBLE_IOCTL(PPPIOCGASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCSASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCGUNIT)
-COMPATIBLE_IOCTL(PPPIOCGRASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCSRASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCGMRU)
-COMPATIBLE_IOCTL(PPPIOCSMRU)
-COMPATIBLE_IOCTL(PPPIOCSMAXCID)
-COMPATIBLE_IOCTL(PPPIOCGXASYNCMAP)
-COMPATIBLE_IOCTL(LPGETSTATUS)
-COMPATIBLE_IOCTL(PPPIOCSXASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCXFERUNIT)
-COMPATIBLE_IOCTL(PPPIOCGNPMODE)
-COMPATIBLE_IOCTL(PPPIOCSNPMODE)
-COMPATIBLE_IOCTL(PPPIOCGDEBUG)
-COMPATIBLE_IOCTL(PPPIOCSDEBUG)
-COMPATIBLE_IOCTL(PPPIOCNEWUNIT)
-COMPATIBLE_IOCTL(PPPIOCATTACH)
-COMPATIBLE_IOCTL(PPPIOCDETACH)
-COMPATIBLE_IOCTL(PPPIOCSMRRU)
-COMPATIBLE_IOCTL(PPPIOCCONNECT)
-COMPATIBLE_IOCTL(PPPIOCDISCONN)
-COMPATIBLE_IOCTL(PPPIOCATTCHAN)
-COMPATIBLE_IOCTL(PPPIOCGCHAN)
-/* PPPOX */
-COMPATIBLE_IOCTL(PPPOEIOCSFWD)
-COMPATIBLE_IOCTL(PPPOEIOCDFWD)
-/* CDROM stuff */
-COMPATIBLE_IOCTL(CDROMPAUSE)
-COMPATIBLE_IOCTL(CDROMRESUME)
-COMPATIBLE_IOCTL(CDROMPLAYMSF)
-COMPATIBLE_IOCTL(CDROMPLAYTRKIND)
-COMPATIBLE_IOCTL(CDROMREADTOCHDR)
-COMPATIBLE_IOCTL(CDROMREADTOCENTRY)
-COMPATIBLE_IOCTL(CDROMSTOP)
-COMPATIBLE_IOCTL(CDROMSTART)
-COMPATIBLE_IOCTL(CDROMEJECT)
-COMPATIBLE_IOCTL(CDROMVOLCTRL)
-COMPATIBLE_IOCTL(CDROMSUBCHNL)
-COMPATIBLE_IOCTL(CDROMEJECT_SW)
-COMPATIBLE_IOCTL(CDROMMULTISESSION)
-COMPATIBLE_IOCTL(CDROM_GET_MCN)
-COMPATIBLE_IOCTL(CDROMRESET)
-COMPATIBLE_IOCTL(CDROMVOLREAD)
-COMPATIBLE_IOCTL(CDROMSEEK)
-COMPATIBLE_IOCTL(CDROMPLAYBLK)
-COMPATIBLE_IOCTL(CDROMCLOSETRAY)
-COMPATIBLE_IOCTL(CDROM_SET_OPTIONS)
-COMPATIBLE_IOCTL(CDROM_CLEAR_OPTIONS)
-COMPATIBLE_IOCTL(CDROM_SELECT_SPEED)
-COMPATIBLE_IOCTL(CDROM_SELECT_DISC)
-COMPATIBLE_IOCTL(CDROM_MEDIA_CHANGED)
-COMPATIBLE_IOCTL(CDROM_DRIVE_STATUS)
-COMPATIBLE_IOCTL(CDROM_DISC_STATUS)
-COMPATIBLE_IOCTL(CDROM_CHANGER_NSLOTS)
-COMPATIBLE_IOCTL(CDROM_LOCKDOOR)
-COMPATIBLE_IOCTL(CDROM_DEBUG)
-COMPATIBLE_IOCTL(CDROM_GET_CAPABILITY)
-/* DVD ioctls */
-COMPATIBLE_IOCTL(DVD_READ_STRUCT)
-COMPATIBLE_IOCTL(DVD_WRITE_STRUCT)
-COMPATIBLE_IOCTL(DVD_AUTH)
-/* Big L */
-COMPATIBLE_IOCTL(LOOP_SET_FD)
-COMPATIBLE_IOCTL(LOOP_CLR_FD)
-/* Big Q for sound/OSS */
-COMPATIBLE_IOCTL(SNDCTL_SEQ_RESET)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_SYNC)
-COMPATIBLE_IOCTL(SNDCTL_SYNTH_INFO)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_CTRLRATE)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_GETOUTCOUNT)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_GETINCOUNT)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_PERCMODE)
-COMPATIBLE_IOCTL(SNDCTL_FM_LOAD_INSTR)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_TESTMIDI)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_RESETSAMPLES)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_NRSYNTHS)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_NRMIDIS)
-COMPATIBLE_IOCTL(SNDCTL_MIDI_INFO)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_THRESHOLD)
-COMPATIBLE_IOCTL(SNDCTL_SYNTH_MEMAVL)
-COMPATIBLE_IOCTL(SNDCTL_FM_4OP_ENABLE)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_PANIC)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_OUTOFBAND)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_GETTIME)
-COMPATIBLE_IOCTL(SNDCTL_SYNTH_ID)
-COMPATIBLE_IOCTL(SNDCTL_SYNTH_CONTROL)
-COMPATIBLE_IOCTL(SNDCTL_SYNTH_REMOVESAMPLE)
-/* Big T for sound/OSS */
-COMPATIBLE_IOCTL(SNDCTL_TMR_TIMEBASE)
-COMPATIBLE_IOCTL(SNDCTL_TMR_START)
-COMPATIBLE_IOCTL(SNDCTL_TMR_STOP)
-COMPATIBLE_IOCTL(SNDCTL_TMR_CONTINUE)
-COMPATIBLE_IOCTL(SNDCTL_TMR_TEMPO)
-COMPATIBLE_IOCTL(SNDCTL_TMR_SOURCE)
-COMPATIBLE_IOCTL(SNDCTL_TMR_METRONOME)
-COMPATIBLE_IOCTL(SNDCTL_TMR_SELECT)
-/* Little m for sound/OSS */
-COMPATIBLE_IOCTL(SNDCTL_MIDI_PRETIME)
-COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUMODE)
-COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUCMD)
-/* Big P for sound/OSS */
-COMPATIBLE_IOCTL(SNDCTL_DSP_RESET)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SYNC)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SPEED)
-COMPATIBLE_IOCTL(SNDCTL_DSP_STEREO)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETBLKSIZE)
-COMPATIBLE_IOCTL(SNDCTL_DSP_CHANNELS)
-COMPATIBLE_IOCTL(SOUND_PCM_WRITE_FILTER)
-COMPATIBLE_IOCTL(SNDCTL_DSP_POST)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SUBDIVIDE)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SETFRAGMENT)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETFMTS)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SETFMT)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETOSPACE)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETISPACE)
-COMPATIBLE_IOCTL(SNDCTL_DSP_NONBLOCK)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETCAPS)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETTRIGGER)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SETTRIGGER)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETIPTR)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETOPTR)
-/* SNDCTL_DSP_MAPINBUF, XXX needs translation */
-/* SNDCTL_DSP_MAPOUTBUF, XXX needs translation */
-COMPATIBLE_IOCTL(SNDCTL_DSP_SETSYNCRO)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SETDUPLEX)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETODELAY)
-COMPATIBLE_IOCTL(SNDCTL_DSP_PROFILE)
-COMPATIBLE_IOCTL(SOUND_PCM_READ_RATE)
-COMPATIBLE_IOCTL(SOUND_PCM_READ_CHANNELS)
-COMPATIBLE_IOCTL(SOUND_PCM_READ_BITS)
-COMPATIBLE_IOCTL(SOUND_PCM_READ_FILTER)
-/* Big C for sound/OSS */
-COMPATIBLE_IOCTL(SNDCTL_COPR_RESET)
-COMPATIBLE_IOCTL(SNDCTL_COPR_LOAD)
-COMPATIBLE_IOCTL(SNDCTL_COPR_RDATA)
-COMPATIBLE_IOCTL(SNDCTL_COPR_RCODE)
-COMPATIBLE_IOCTL(SNDCTL_COPR_WDATA)
-COMPATIBLE_IOCTL(SNDCTL_COPR_WCODE)
-COMPATIBLE_IOCTL(SNDCTL_COPR_RUN)
-COMPATIBLE_IOCTL(SNDCTL_COPR_HALT)
-COMPATIBLE_IOCTL(SNDCTL_COPR_SENDMSG)
-COMPATIBLE_IOCTL(SNDCTL_COPR_RCVMSG)
-/* Big M for sound/OSS */
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_VOLUME)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_BASS)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_TREBLE)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_SYNTH)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_PCM)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_SPEAKER)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_MIC)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_CD)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_IMIX)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_ALTPCM)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECLEV)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_IGAIN)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_OGAIN)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE1)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE2)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE3)
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL1))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL2))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL3))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEIN))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEOUT))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_VIDEO))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_RADIO))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_MONITOR))
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_MUTE)
-/* SOUND_MIXER_READ_ENHANCE, same value as READ_MUTE */
-/* SOUND_MIXER_READ_LOUD, same value as READ_MUTE */
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECSRC)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_DEVMASK)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECMASK)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_STEREODEVS)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_CAPS)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_VOLUME)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_BASS)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_TREBLE)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SYNTH)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_PCM)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SPEAKER)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MIC)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_CD)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IMIX)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_ALTPCM)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECLEV)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IGAIN)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_OGAIN)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE1)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE2)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE3)
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL1))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL2))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL3))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEIN))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEOUT))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_VIDEO))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_RADIO))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_MONITOR))
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MUTE)
-/* SOUND_MIXER_WRITE_ENHANCE, same value as WRITE_MUTE */
-/* SOUND_MIXER_WRITE_LOUD, same value as WRITE_MUTE */
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECSRC)
-COMPATIBLE_IOCTL(SOUND_MIXER_INFO)
-COMPATIBLE_IOCTL(SOUND_OLD_MIXER_INFO)
-COMPATIBLE_IOCTL(SOUND_MIXER_ACCESS)
-COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE1)
-COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE2)
-COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE3)
-COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE4)
-COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE5)
-COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS)
-COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS)
-COMPATIBLE_IOCTL(OSS_GETVERSION)
-/* AUTOFS */
-COMPATIBLE_IOCTL(AUTOFS_IOC_READY)
-COMPATIBLE_IOCTL(AUTOFS_IOC_FAIL)
-COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC)
-COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER)
-COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE)
-/* DEVFS */
-COMPATIBLE_IOCTL(DEVFSDIOC_GET_PROTO_REV)
-COMPATIBLE_IOCTL(DEVFSDIOC_SET_EVENT_MASK)
-COMPATIBLE_IOCTL(DEVFSDIOC_RELEASE_EVENT_QUEUE)
-COMPATIBLE_IOCTL(DEVFSDIOC_SET_DEBUG_MASK)
-/* Raw devices */
-COMPATIBLE_IOCTL(RAW_SETBIND)
-COMPATIBLE_IOCTL(RAW_GETBIND)
-/* SMB ioctls which do not need any translations */
-COMPATIBLE_IOCTL(SMB_IOC_NEWCONN)
-/* NCP ioctls which do not need any translations */
-COMPATIBLE_IOCTL(NCP_IOC_CONN_LOGGED_IN)
-COMPATIBLE_IOCTL(NCP_IOC_SIGN_INIT)
-COMPATIBLE_IOCTL(NCP_IOC_SIGN_WANTED)
-COMPATIBLE_IOCTL(NCP_IOC_SET_SIGN_WANTED)
-COMPATIBLE_IOCTL(NCP_IOC_LOCKUNLOCK)
-COMPATIBLE_IOCTL(NCP_IOC_GETROOT)
-COMPATIBLE_IOCTL(NCP_IOC_SETROOT)
-COMPATIBLE_IOCTL(NCP_IOC_GETCHARSETS)
-COMPATIBLE_IOCTL(NCP_IOC_SETCHARSETS)
-COMPATIBLE_IOCTL(NCP_IOC_GETDENTRYTTL)
-COMPATIBLE_IOCTL(NCP_IOC_SETDENTRYTTL)
-/* Little a */
-COMPATIBLE_IOCTL(ATMSIGD_CTRL)
-COMPATIBLE_IOCTL(ATMARPD_CTRL)
-COMPATIBLE_IOCTL(ATMLEC_CTRL)
-COMPATIBLE_IOCTL(ATMLEC_MCAST)
-COMPATIBLE_IOCTL(ATMLEC_DATA)
-COMPATIBLE_IOCTL(ATM_SETSC)
-COMPATIBLE_IOCTL(SIOCSIFATMTCP)
-COMPATIBLE_IOCTL(SIOCMKCLIP)
-COMPATIBLE_IOCTL(ATMARP_MKIP)
-COMPATIBLE_IOCTL(ATMARP_SETENTRY)
-COMPATIBLE_IOCTL(ATMARP_ENCAP)
-COMPATIBLE_IOCTL(ATMTCP_CREATE)
-COMPATIBLE_IOCTL(ATMTCP_REMOVE)
-COMPATIBLE_IOCTL(ATMMPC_CTRL)
-COMPATIBLE_IOCTL(ATMMPC_DATA)
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC)
-COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID)
-COMPATIBLE_IOCTL(DRM_IOCTL_AUTH_MAGIC)
-COMPATIBLE_IOCTL(DRM_IOCTL_BLOCK)
-COMPATIBLE_IOCTL(DRM_IOCTL_UNBLOCK)
-COMPATIBLE_IOCTL(DRM_IOCTL_CONTROL)
-COMPATIBLE_IOCTL(DRM_IOCTL_ADD_BUFS)
-COMPATIBLE_IOCTL(DRM_IOCTL_MARK_BUFS)
-COMPATIBLE_IOCTL(DRM_IOCTL_ADD_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_RM_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_MOD_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_GET_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_SWITCH_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_NEW_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_ADD_DRAW)
-COMPATIBLE_IOCTL(DRM_IOCTL_RM_DRAW)
-COMPATIBLE_IOCTL(DRM_IOCTL_LOCK)
-COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK)
-COMPATIBLE_IOCTL(DRM_IOCTL_FINISH)
-#endif /* DRM */
-/* Big W */
-/* WIOC_GETSUPPORT not yet implemented -E */
-COMPATIBLE_IOCTL(WDIOC_GETSTATUS)
-COMPATIBLE_IOCTL(WDIOC_GETBOOTSTATUS)
-COMPATIBLE_IOCTL(WDIOC_GETTEMP)
-COMPATIBLE_IOCTL(WDIOC_SETOPTIONS)
-COMPATIBLE_IOCTL(WDIOC_KEEPALIVE)
-/* Big R */
-COMPATIBLE_IOCTL(RNDGETENTCNT)
-COMPATIBLE_IOCTL(RNDADDTOENTCNT)
-COMPATIBLE_IOCTL(RNDGETPOOL)
-COMPATIBLE_IOCTL(RNDADDENTROPY)
-COMPATIBLE_IOCTL(RNDZAPENTCNT)
-COMPATIBLE_IOCTL(RNDCLEARPOOL)
-/* Bluetooth ioctls */
-COMPATIBLE_IOCTL(HCIDEVUP)
-COMPATIBLE_IOCTL(HCIDEVDOWN)
-COMPATIBLE_IOCTL(HCIDEVRESET)
-COMPATIBLE_IOCTL(HCIDEVRESTAT)
-COMPATIBLE_IOCTL(HCIGETDEVLIST)
-COMPATIBLE_IOCTL(HCIGETDEVINFO)
-COMPATIBLE_IOCTL(HCIGETCONNLIST)
-COMPATIBLE_IOCTL(HCIGETCONNINFO)
-COMPATIBLE_IOCTL(HCISETRAW)
-COMPATIBLE_IOCTL(HCISETSCAN)
-COMPATIBLE_IOCTL(HCISETAUTH)
-COMPATIBLE_IOCTL(HCISETENCRYPT)
-COMPATIBLE_IOCTL(HCISETPTYPE)
-COMPATIBLE_IOCTL(HCISETLINKPOL)
-COMPATIBLE_IOCTL(HCISETLINKMODE)
-COMPATIBLE_IOCTL(HCISETACLMTU)
-COMPATIBLE_IOCTL(HCISETSCOMTU)
-COMPATIBLE_IOCTL(HCIINQUIRY)
-COMPATIBLE_IOCTL(HCIUARTSETPROTO)
-COMPATIBLE_IOCTL(HCIUARTGETPROTO)
-COMPATIBLE_IOCTL(RFCOMMCREATEDEV)
-COMPATIBLE_IOCTL(RFCOMMRELEASEDEV)
-COMPATIBLE_IOCTL(RFCOMMGETDEVLIST)
-COMPATIBLE_IOCTL(RFCOMMGETDEVINFO)
-COMPATIBLE_IOCTL(RFCOMMSTEALDLC)
-COMPATIBLE_IOCTL(BNEPCONNADD)
-COMPATIBLE_IOCTL(BNEPCONNDEL)
-COMPATIBLE_IOCTL(BNEPGETCONNLIST)
-COMPATIBLE_IOCTL(BNEPGETCONNINFO)
-COMPATIBLE_IOCTL(PCIIOC_CONTROLLER)
-COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO)
-COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM)
-COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE)
-/* USB */
-COMPATIBLE_IOCTL(USBDEVFS_RESETEP)
-COMPATIBLE_IOCTL(USBDEVFS_SETINTERFACE)
-COMPATIBLE_IOCTL(USBDEVFS_SETCONFIGURATION)
-COMPATIBLE_IOCTL(USBDEVFS_GETDRIVER)
-COMPATIBLE_IOCTL(USBDEVFS_DISCARDURB)
-COMPATIBLE_IOCTL(USBDEVFS_CLAIMINTERFACE)
-COMPATIBLE_IOCTL(USBDEVFS_RELEASEINTERFACE)
-COMPATIBLE_IOCTL(USBDEVFS_CONNECTINFO)
-COMPATIBLE_IOCTL(USBDEVFS_HUB_PORTINFO)
-COMPATIBLE_IOCTL(USBDEVFS_RESET)
-COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT)
-/* MTD */
-COMPATIBLE_IOCTL(MEMGETINFO)
-COMPATIBLE_IOCTL(MEMERASE)
-COMPATIBLE_IOCTL(MEMLOCK)
-COMPATIBLE_IOCTL(MEMUNLOCK)
-COMPATIBLE_IOCTL(MEMGETREGIONCOUNT)
-COMPATIBLE_IOCTL(MEMGETREGIONINFO)
-/* NBD */
-COMPATIBLE_IOCTL(NBD_SET_SOCK)
-COMPATIBLE_IOCTL(NBD_SET_BLKSIZE)
-COMPATIBLE_IOCTL(NBD_SET_SIZE)
-COMPATIBLE_IOCTL(NBD_DO_IT)
-COMPATIBLE_IOCTL(NBD_CLEAR_SOCK)
-COMPATIBLE_IOCTL(NBD_CLEAR_QUE)
-COMPATIBLE_IOCTL(NBD_PRINT_DEBUG)
-COMPATIBLE_IOCTL(NBD_SET_SIZE_BLOCKS)
-COMPATIBLE_IOCTL(NBD_DISCONNECT)
-/* device-mapper */
-COMPATIBLE_IOCTL(DM_VERSION)
-COMPATIBLE_IOCTL(DM_REMOVE_ALL)
-COMPATIBLE_IOCTL(DM_DEV_CREATE)
-COMPATIBLE_IOCTL(DM_DEV_REMOVE)
-COMPATIBLE_IOCTL(DM_DEV_RELOAD)
-COMPATIBLE_IOCTL(DM_DEV_SUSPEND)
-COMPATIBLE_IOCTL(DM_DEV_RENAME)
-COMPATIBLE_IOCTL(DM_DEV_DEPS)
-COMPATIBLE_IOCTL(DM_DEV_STATUS)
-COMPATIBLE_IOCTL(DM_TARGET_STATUS)
-COMPATIBLE_IOCTL(DM_TARGET_WAIT)
+
/* And these ioctls need translation */
-HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob)
-HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob)
-#ifdef CONFIG_NET
-HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32)
-#endif
-HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf)
-HANDLE_IOCTL(SIOCGIFFLAGS, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFFLAGS, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFMETRIC, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFMETRIC, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFMTU, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFMTU, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFMEM, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFMEM, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFHWADDR, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFHWADDR, dev_ifsioc)
-HANDLE_IOCTL(SIOCADDMULTI, dev_ifsioc)
-HANDLE_IOCTL(SIOCDELMULTI, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFINDEX, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFMAP, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFMAP, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFADDR, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFADDR, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFBRDADDR, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFBRDADDR, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFDSTADDR, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFDSTADDR, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFNETMASK, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFNETMASK, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFPFLAGS, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFPFLAGS, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc)
-HANDLE_IOCTL(SIOCETHTOOL, ethtool_ioctl)
-HANDLE_IOCTL(SIOCBONDENSLAVE, bond_ioctl)
-HANDLE_IOCTL(SIOCBONDRELEASE, bond_ioctl)
-HANDLE_IOCTL(SIOCBONDSETHWADDR, bond_ioctl)
-HANDLE_IOCTL(SIOCBONDSLAVEINFOQUERY, bond_ioctl)
-HANDLE_IOCTL(SIOCBONDINFOQUERY, bond_ioctl)
-HANDLE_IOCTL(SIOCBONDCHANGEACTIVE, bond_ioctl)
-HANDLE_IOCTL(SIOCADDRT, routing_ioctl)
-HANDLE_IOCTL(SIOCDELRT, routing_ioctl)
-/* Note SIOCRTMSG is no longer, so this is safe and
- * the user would have seen just an -EINVAL anyways. */
-HANDLE_IOCTL(SIOCRTMSG, ret_einval)
-HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp)
-HANDLE_IOCTL(HDIO_GETGEO, hdio_getgeo)
HANDLE_IOCTL(HDIO_GETGEO_BIG_RAW, hdio_getgeo_big)
-HANDLE_IOCTL(BLKGETSIZE, w_long)
-HANDLE_IOCTL(BLKRAGET, w_long)
-HANDLE_IOCTL(BLKFRAGET, w_long)
-HANDLE_IOCTL(0x1260, broken_blkgetsize)
-HANDLE_IOCTL(BLKSECTGET, w_long)
-HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans)
-HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans)
-HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans)
-HANDLE_IOCTL(HDIO_GET_32BIT, hdio_ioctl_trans)
-HANDLE_IOCTL(HDIO_GET_MULTCOUNT, hdio_ioctl_trans)
-HANDLE_IOCTL(HDIO_GET_NOWERR, hdio_ioctl_trans)
-HANDLE_IOCTL(HDIO_GET_NICE, hdio_ioctl_trans)
-HANDLE_IOCTL(FDSETPRM32, fd_ioctl_trans)
-HANDLE_IOCTL(FDDEFPRM32, fd_ioctl_trans)
-HANDLE_IOCTL(FDGETPRM32, fd_ioctl_trans)
-HANDLE_IOCTL(FDSETDRVPRM32, fd_ioctl_trans)
-HANDLE_IOCTL(FDGETDRVPRM32, fd_ioctl_trans)
-HANDLE_IOCTL(FDGETDRVSTAT32, fd_ioctl_trans)
-HANDLE_IOCTL(FDPOLLDRVSTAT32, fd_ioctl_trans)
-HANDLE_IOCTL(FDGETFDCSTAT32, fd_ioctl_trans)
-HANDLE_IOCTL(FDWERRORGET32, fd_ioctl_trans)
-HANDLE_IOCTL(SG_IO,sg_ioctl_trans)
-HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans)
-HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans)
-HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans)
-HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans)
-HANDLE_IOCTL(MTIOCGETCONFIG32, mt_ioctl_trans)
-HANDLE_IOCTL(MTIOCSETCONFIG32, mt_ioctl_trans)
-HANDLE_IOCTL(CDROMREADMODE2, cdrom_ioctl_trans)
-HANDLE_IOCTL(CDROMREADMODE1, cdrom_ioctl_trans)
-HANDLE_IOCTL(CDROMREADRAW, cdrom_ioctl_trans)
-HANDLE_IOCTL(CDROMREADCOOKED, cdrom_ioctl_trans)
-HANDLE_IOCTL(CDROMREADAUDIO, cdrom_ioctl_trans)
-HANDLE_IOCTL(CDROMREADALL, cdrom_ioctl_trans)
-HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans)
-HANDLE_IOCTL(LOOP_SET_STATUS, loop_status)
-HANDLE_IOCTL(LOOP_GET_STATUS, loop_status)
-HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout)
-#ifdef CONFIG_VT
-HANDLE_IOCTL(PIO_FONTX, do_fontx_ioctl)
-HANDLE_IOCTL(GIO_FONTX, do_fontx_ioctl)
-HANDLE_IOCTL(PIO_UNIMAP, do_unimap_ioctl)
-HANDLE_IOCTL(GIO_UNIMAP, do_unimap_ioctl)
-HANDLE_IOCTL(KDFONTOP, do_kdfontop_ioctl)
-HANDLE_IOCTL(FBIOGET_FSCREENINFO, do_fbioget_fscreeninfo_ioctl)
-HANDLE_IOCTL(FBIOGETCMAP, do_fbiogetcmap_ioctl)
-HANDLE_IOCTL(FBIOPUTCMAP, do_fbioputcmap_ioctl)
-#endif
-HANDLE_IOCTL(EXT2_IOC32_GETFLAGS, do_ext2_ioctl)
-HANDLE_IOCTL(EXT2_IOC32_SETFLAGS, do_ext2_ioctl)
-HANDLE_IOCTL(EXT2_IOC32_GETVERSION, do_ext2_ioctl)
-HANDLE_IOCTL(EXT2_IOC32_SETVERSION, do_ext2_ioctl)
-HANDLE_IOCTL(VIDIOCGTUNER32, do_video_ioctl)
-HANDLE_IOCTL(VIDIOCSTUNER32, do_video_ioctl)
-HANDLE_IOCTL(VIDIOCGWIN32, do_video_ioctl)
-HANDLE_IOCTL(VIDIOCSWIN32, do_video_ioctl)
-HANDLE_IOCTL(VIDIOCGFBUF32, do_video_ioctl)
-HANDLE_IOCTL(VIDIOCSFBUF32, do_video_ioctl)
-HANDLE_IOCTL(VIDIOCGFREQ32, do_video_ioctl)
-HANDLE_IOCTL(VIDIOCSFREQ32, do_video_ioctl)
-/* One SMB ioctl needs translations. */
-HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid)
+
/* NCPFS */
HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest)
HANDLE_IOCTL(NCP_IOC_GETMOUNTUID2_32, do_ncp_getmountuid2)
@@ -4426,51 +783,12 @@
HANDLE_IOCTL(NCP_IOC_SETOBJECTNAME_32, do_ncp_setobjectname)
HANDLE_IOCTL(NCP_IOC_GETPRIVATEDATA_32, do_ncp_getprivatedata)
HANDLE_IOCTL(NCP_IOC_SETPRIVATEDATA_32, do_ncp_setprivatedata)
-HANDLE_IOCTL(ATM_GETLINKRATE32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETNAMES32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETTYPE32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETESI32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETADDR32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_RSTADDR32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_ADDADDR32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_DELADDR32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETCIRANGE32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_SETCIRANGE32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_SETESI32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_SETESIF32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETSTAT32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETSTATZ32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETLOOP32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_SETLOOP32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_QUERYLOOP32, do_atm_ioctl)
-HANDLE_IOCTL(SONET_GETSTAT, do_atm_ioctl)
-HANDLE_IOCTL(SONET_GETSTATZ, do_atm_ioctl)
-HANDLE_IOCTL(SONET_GETDIAG, do_atm_ioctl)
-HANDLE_IOCTL(SONET_SETDIAG, do_atm_ioctl)
-HANDLE_IOCTL(SONET_CLRDIAG, do_atm_ioctl)
-HANDLE_IOCTL(SONET_SETFRAMING, do_atm_ioctl)
-HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl)
-HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl)
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version)
-HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique)
-HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique)
-HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap)
-HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs)
-HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs)
-HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs)
-HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma)
-HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx)
-#endif /* DRM */
+
+/* USB devfs */
HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control)
HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk)
/*HANDLE_IOCTL(USBDEVFS_SUBMITURB32, do_usbdevfs_urb)*/
HANDLE_IOCTL(USBDEVFS_REAPURB32, do_usbdevfs_reapurb)
HANDLE_IOCTL(USBDEVFS_REAPURBNDELAY32, do_usbdevfs_reapurb)
HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal)
-/* take care of sizeof(sizeof()) breakage */
-/* block stuff */
-HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget)
-HANDLE_IOCTL(BLKBSZSET_32, do_blkbszset)
-HANDLE_IOCTL(BLKGETSIZE64_32, do_blkgetsize64)
-};
+IOCTL_TABLE_END
diff -Nru a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c
--- a/arch/ppc64/kernel/irq.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/irq.c Thu Jun 19 00:45:34 2003
@@ -63,8 +63,11 @@
volatile unsigned char *chrp_int_ack_special;
static void register_irq_proc (unsigned int irq);
-irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
- { [0 ... NR_IRQS-1] = { 0, NULL, NULL, 0, SPIN_LOCK_UNLOCKED}};
+irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = {
+ [0 ... NR_IRQS-1] = {
+ .lock = SPIN_LOCK_UNLOCKED
+ }
+};
int ppc_spurious_interrupts = 0;
unsigned long lpEvent_count = 0;
@@ -380,22 +383,48 @@
return 0;
}
-static inline void
-handle_irq_event(int irq, struct pt_regs *regs, struct irqaction *action)
+extern char *ppc_find_proc_name(unsigned *p, char *buf, unsigned buflen);
+
+static inline void handle_irq_event(int irq, struct pt_regs *regs,
+ struct irqaction *action)
{
int status = 0;
+ int retval = 0;
+ struct irqaction *first_action = action;
if (!(action->flags & SA_INTERRUPT))
local_irq_enable();
do {
status |= action->flags;
- action->handler(irq, action->dev_id, regs);
+ retval |= action->handler(irq, action->dev_id, regs);
action = action->next;
} while (action);
if (status & SA_SAMPLE_RANDOM)
add_interrupt_randomness(irq);
local_irq_disable();
+ if (retval != 1) {
+ static int count = 100;
+ char name_buf[256];
+ if (count) {
+ count--;
+ if (retval) {
+ printk("irq event %d: bogus retval mask %x\n",
+ irq, retval);
+ } else {
+ printk("irq %d: nobody cared!\n", irq);
+ }
+ dump_stack();
+ printk("handlers:\n");
+ action = first_action;
+ do {
+ printk("[<%p>]", action->handler);
+ printk(" (%s)\n",
+ ppc_find_proc_name((unsigned *)action->handler, name_buf, 256));
+ action = action->next;
+ } while (action);
+ }
+ }
}
/*
@@ -566,7 +595,6 @@
once++;
ppc_md.init_IRQ();
- if(ppc_md.init_ras_IRQ) ppc_md.init_ras_IRQ();
}
static struct proc_dir_entry * root_irq_dir;
@@ -675,7 +703,7 @@
#ifdef CONFIG_PPC_ISERIES
{
unsigned i;
- for (i=0; i<MAX_PACAS; ++i) {
+ for (i=0; i<NR_CPUS; ++i) {
if ( paca[i].prof_buffer && (new_value & 1) )
paca[i].prof_enabled = 1;
else
diff -Nru a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
--- a/arch/ppc64/kernel/misc.S Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/misc.S Thu Jun 19 00:45:34 2003
@@ -27,6 +27,7 @@
#include <asm/cache.h>
#include <asm/ppc_asm.h>
#include <asm/offsets.h>
+#include <asm/cputable.h>
.text
@@ -439,6 +440,95 @@
blr
/*
+ * identify_cpu,
+ * In: r3 = base of the cpu_specs array
+ * r4 = address of cur_cpu_spec
+ * r5 = relocation offset
+ */
+_GLOBAL(identify_cpu)
+ mfpvr r7
+1:
+ lwz r8,CPU_SPEC_PVR_MASK(r3)
+ and r8,r8,r7
+ lwz r9,CPU_SPEC_PVR_VALUE(r3)
+ cmplw 0,r9,r8
+ beq 1f
+ addi r3,r3,CPU_SPEC_ENTRY_SIZE
+ b 1b
+1:
+ add r3,r3,r5
+ std r3,0(r4)
+ blr
+
+/*
+ * do_cpu_ftr_fixups - goes through the list of CPU feature fixups
+ * and writes nop's over sections of code that don't apply for this cpu.
+ * r3 = data offset (not changed)
+ */
+_GLOBAL(do_cpu_ftr_fixups)
+ /* Get CPU 0 features */
+ LOADADDR(r6,cur_cpu_spec)
+ sub r6,r6,r3
+ ld r4,0(r6)
+ sub r4,r4,r3
+ ld r4,CPU_SPEC_FEATURES(r4)
+ /* Get the fixup table */
+ LOADADDR(r6,__start___ftr_fixup)
+ sub r6,r6,r3
+ LOADADDR(r7,__stop___ftr_fixup)
+ sub r7,r7,r3
+ /* Do the fixup */
+1: cmpld r6,r7
+ bgelr
+ addi r6,r6,32
+ ld r8,-32(r6) /* mask */
+ and r8,r8,r4
+ ld r9,-24(r6) /* value */
+ cmpld r8,r9
+ beq 1b
+ ld r8,-16(r6) /* section begin */
+ ld r9,-8(r6) /* section end */
+ subf. r9,r8,r9
+ beq 1b
+ /* write nops over the section of code */
+ /* todo: if large section, add a branch at the start of it */
+ srwi r9,r9,2
+ mtctr r9
+ sub r8,r8,r3
+ lis r0,0x60000000@h /* nop */
+3: stw r0,0(r8)
+ andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l
+ beq 2f
+ dcbst 0,r8 /* suboptimal, but simpler */
+ sync
+ icbi 0,r8
+2: addi r8,r8,4
+ bdnz 3b
+ sync /* additional sync needed on g4 */
+ isync
+ b 1b
+
+/*
+ * call_setup_cpu - call the setup_cpu function for this cpu
+ * r3 = data offset
+ *
+ * Setup function is called with:
+ * r3 = data offset
+ * r4 = ptr to CPU spec (relocated)
+ */
+_GLOBAL(call_setup_cpu)
+ LOADADDR(r4, cur_cpu_spec)
+ sub r4,r4,r3
+ lwz r4,0(r4) # load pointer to cpu_spec
+ sub r4,r4,r3 # relocate
+ lwz r6,CPU_SPEC_SETUP(r4) # load function pointer
+ sub r6,r6,r3
+ mtctr r6
+ bctr
+
+
+
+/*
* Create a kernel thread
* kernel_thread(fn, arg, flags)
*/
@@ -603,7 +693,7 @@
.llong .sys_ni_syscall /* old profil syscall */
.llong .compat_sys_statfs
.llong .compat_sys_fstatfs /* 100 */
- .llong .sys_ioperm
+ .llong .sys_ni_syscall /* old ioperm syscall */
.llong .compat_sys_socketcall
.llong .sys32_syslog
.llong .compat_sys_setitimer
@@ -729,11 +819,11 @@
.llong .sys_ni_syscall
.llong .sys_ni_syscall /* 225 - reserved for tux */
.llong .sys32_sendfile64
- .llong .sys_ni_syscall /* reserved for sys_io_setup */
- .llong .sys_ni_syscall /* reserved for sys_io_destroy */
- .llong .sys_ni_syscall /* reserved for sys_io_getevents */
- .llong .sys_ni_syscall /* 230 - reserved for sys_io_submit */
- .llong .sys_ni_syscall /* reserved for sys_io_cancel */
+ .llong .sys32_io_setup
+ .llong .sys_io_destroy
+ .llong .sys32_io_getevents
+ .llong .sys32_io_submit
+ .llong .sys_io_cancel
.llong .sys_set_tid_address
.llong .ppc32_fadvise64
.llong .sys_exit_group
@@ -846,7 +936,7 @@
.llong .sys_ni_syscall /* old profil syscall holder */
.llong .sys_statfs
.llong .sys_fstatfs /* 100 */
- .llong .sys_ioperm
+ .llong .sys_ni_syscall /* old ioperm syscall */
.llong .sys_socketcall
.llong .sys_syslog
.llong .sys_setitimer
diff -Nru a/arch/ppc64/kernel/module.c b/arch/ppc64/kernel/module.c
--- a/arch/ppc64/kernel/module.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/module.c Thu Jun 19 00:45:34 2003
@@ -20,6 +20,8 @@
#include <linux/moduleloader.h>
#include <linux/err.h>
#include <linux/vmalloc.h>
+#include <asm/module.h>
+#include <asm/uaccess.h>
/* FIXME: We don't do .init separately. To do this, we'd need to have
a separate r2 value in the init and core section, and stub between
@@ -374,15 +376,57 @@
return 0;
}
-/* In arch/ppc64/mm/extable.c */
-extern void sort_ex_table(struct exception_table_entry *start,
- struct exception_table_entry *finish);
+LIST_HEAD(module_bug_list);
int module_finalize(const Elf_Ehdr *hdr,
- const Elf_Shdr *sechdrs,
- struct module *me)
+ const Elf_Shdr *sechdrs, struct module *me)
{
- sort_ex_table(me->extable.entry,
- me->extable.entry + me->extable.num_entries);
+ char *secstrings;
+ unsigned int i;
+
+ me->arch.bug_table = NULL;
+ me->arch.num_bugs = 0;
+
+ /* Find the __bug_table section, if present */
+ secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+ for (i = 1; i < hdr->e_shnum; i++) {
+ if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table"))
+ continue;
+ me->arch.bug_table = (void *) sechdrs[i].sh_addr;
+ me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry);
+ break;
+ }
+
+ /*
+ * Strictly speaking this should have a spinlock to protect against
+ * traversals, but since we only traverse on BUG()s, a spinlock
+ * could potentially lead to deadlock and thus be counter-productive.
+ */
+ list_add(&me->arch.bug_list, &module_bug_list);
+
+ sort_ex_table((struct exception_table_entry *)me->extable,
+ (struct exception_table_entry *)me->extable +
+ me->num_exentries);
+
return 0;
+}
+
+void module_arch_cleanup(struct module *mod)
+{
+ list_del(&mod->arch.bug_list);
+}
+
+struct bug_entry *module_find_bug(unsigned long bugaddr)
+{
+ struct mod_arch_specific *mod;
+ unsigned int i;
+ struct bug_entry *bug;
+
+ list_for_each_entry(mod, &module_bug_list, bug_list) {
+ bug = mod->bug_table;
+ for (i = 0; i < mod->num_bugs; ++i, ++bug)
+ if (bugaddr == bug->bug_addr)
+ return bug;
+ }
+ return NULL;
}
diff -Nru a/arch/ppc64/kernel/pacaData.c b/arch/ppc64/kernel/pacaData.c
--- a/arch/ppc64/kernel/pacaData.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/pacaData.c Thu Jun 19 00:45:34 2003
@@ -63,7 +63,7 @@
(&paca[number].exception_stack[0]) - EXC_FRAME_SIZE, \
}
-struct paca_struct paca[MAX_PACAS] __page_aligned = {
+struct paca_struct paca[NR_CPUS] __page_aligned = {
#ifdef CONFIG_PPC_ISERIES
PACAINITDATA( 0, 1, &xItLpQueue, 0, 0xc000000000005000),
#else
@@ -100,6 +100,7 @@
PACAINITDATA(29, 0, 0, 0, 0),
PACAINITDATA(30, 0, 0, 0, 0),
PACAINITDATA(31, 0, 0, 0, 0),
+#if NR_CPUS > 32
PACAINITDATA(32, 0, 0, 0, 0),
PACAINITDATA(33, 0, 0, 0, 0),
PACAINITDATA(34, 0, 0, 0, 0),
@@ -115,5 +116,22 @@
PACAINITDATA(44, 0, 0, 0, 0),
PACAINITDATA(45, 0, 0, 0, 0),
PACAINITDATA(46, 0, 0, 0, 0),
- PACAINITDATA(47, 0, 0, 0, 0)
+ PACAINITDATA(47, 0, 0, 0, 0),
+ PACAINITDATA(48, 0, 0, 0, 0),
+ PACAINITDATA(49, 0, 0, 0, 0),
+ PACAINITDATA(50, 0, 0, 0, 0),
+ PACAINITDATA(51, 0, 0, 0, 0),
+ PACAINITDATA(52, 0, 0, 0, 0),
+ PACAINITDATA(53, 0, 0, 0, 0),
+ PACAINITDATA(54, 0, 0, 0, 0),
+ PACAINITDATA(55, 0, 0, 0, 0),
+ PACAINITDATA(56, 0, 0, 0, 0),
+ PACAINITDATA(57, 0, 0, 0, 0),
+ PACAINITDATA(58, 0, 0, 0, 0),
+ PACAINITDATA(59, 0, 0, 0, 0),
+ PACAINITDATA(60, 0, 0, 0, 0),
+ PACAINITDATA(61, 0, 0, 0, 0),
+ PACAINITDATA(62, 0, 0, 0, 0),
+ PACAINITDATA(63, 0, 0, 0, 0),
+#endif
};
diff -Nru a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
--- a/arch/ppc64/kernel/pci.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/pci.c Thu Jun 19 00:45:34 2003
@@ -116,14 +116,14 @@
*/
struct pci_dev *pci_find_dev_by_addr(unsigned long addr)
{
- struct pci_dev *dev;
+ struct pci_dev *dev = NULL;
int i;
unsigned long ioaddr;
ioaddr = (addr > isa_io_base) ? addr - isa_io_base : 0;
- pci_for_each_dev(dev) {
- if ((dev->class >> 8) == PCI_BASE_CLASS_BRIDGE)
+ while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+ if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
continue;
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
unsigned long start = pci_resource_start(dev,i);
@@ -370,11 +370,11 @@
}
/*
- * Return the index of the PCI controller for device pdev.
+ * Return the domain number for this bus.
*/
-int pci_controller_num(struct pci_dev *dev)
+int pci_domain_nr(struct pci_bus *bus)
{
- struct pci_controller *hose = PCI_GET_PHB_PTR(dev);
+ struct pci_controller *hose = PCI_GET_PHB_PTR(bus);
return hose->global_number;
}
diff -Nru a/arch/ppc64/kernel/pci_dma.c b/arch/ppc64/kernel/pci_dma.c
--- a/arch/ppc64/kernel/pci_dma.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/pci_dma.c Thu Jun 19 00:45:34 2003
@@ -134,7 +134,7 @@
dev = ppc64_isabridge_dev;
if (!dev)
return NULL;
- if (naca->platform == PLATFORM_ISERIES_LPAR) {
+ if (systemcfg->platform == PLATFORM_ISERIES_LPAR) {
return ISERIES_DEVNODE(dev)->DevTceTable;
} else {
return PCI_GET_DN(dev)->tce_table;
@@ -710,12 +710,6 @@
for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
bus = pci_bus_b(ln);
busdn = PCI_GET_DN(bus);
- /* NOTE: there should never be a window declared on a bus when
- * child devices also have a window. If this should ever be
- * architected, we probably want children to have priority.
- * In reality, the PHB containing ISA has the property, but otherwise
- * it is the pci-bridges that have the property.
- */
dma_window = (u32 *)get_property(busdn, "ibm,dma-window", 0);
if (dma_window) {
/* Bussubno hasn't been copied yet.
@@ -723,16 +717,17 @@
*/
busdn->bussubno = bus->number;
create_pci_bus_tce_table((unsigned long)busdn);
- } else
- create_tce_tables_for_busesLP(&bus->children);
+ }
+ /* look for a window on a bridge even if the PHB had one */
+ create_tce_tables_for_busesLP(&bus->children);
}
}
void create_tce_tables(void) {
- struct pci_dev *dev;
+ struct pci_dev *dev = NULL;
struct device_node *dn, *mydn;
- if (naca->platform == PLATFORM_PSERIES_LPAR) {
+ if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
create_tce_tables_for_busesLP(&pci_root_buses);
}
else {
@@ -742,7 +737,7 @@
* pci device_node. This means get_tce_table() won't need to search
* up the device tree to find it.
*/
- pci_for_each_dev(dev) {
+ while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
mydn = dn = PCI_GET_DN(dev);
while (dn && dn->tce_table == NULL)
dn = dn->parent;
@@ -773,7 +768,7 @@
/* - Tce Table Share between buses, */
/* - Tce Table per logical slot. */
/*****************************************************************/
- if(naca->platform == PLATFORM_ISERIES_LPAR) {
+ if(systemcfg->platform == PLATFORM_ISERIES_LPAR) {
struct iSeries_Device_Node* DevNode = (struct iSeries_Device_Node*)token;
getTceTableParmsiSeries(DevNode,newTceTable);
@@ -797,7 +792,7 @@
dn = (struct device_node *)token;
phb = dn->phb;
- if (naca->platform == PLATFORM_PSERIES)
+ if (systemcfg->platform == PLATFORM_PSERIES)
getTceTableParmsPSeries(phb, dn, newTceTable);
else
getTceTableParmsPSeriesLP(phb, dn, newTceTable);
@@ -1135,7 +1130,8 @@
/* Client asked for way to much space. This is checked later anyway */
/* It is easier to debug here for the drivers than in the tce tables.*/
if(order >= NUM_TCE_LEVELS) {
- printk("PCI_DMA: pci_unmap_single 0x%lx size to large: 0x%lx \n",dma_handle,size);
+ printk("PCI_DMA: pci_unmap_single 0x%lx size too"
+ " large: 0x%lx \n", (long)dma_handle, (long)size);
return;
}
diff -Nru a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c
--- a/arch/ppc64/kernel/process.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/process.c Thu Jun 19 00:45:34 2003
@@ -45,6 +45,7 @@
#include <asm/machdep.h>
#include <asm/iSeries/HvCallHpt.h>
#include <asm/hardirq.h>
+#include <asm/cputable.h>
struct task_struct *last_task_used_math = NULL;
@@ -67,18 +68,34 @@
#endif /* CONFIG_SMP */
}
-int
-dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs)
+#ifdef CONFIG_SMP
+static void smp_unlazy_onefpu(void *arg)
{
- /*
- * XXX temporary workaround until threaded coredumps for ppc64
- * are implemented - Anton
- */
+ struct pt_regs *regs = current->thread.regs;
+
if (!regs)
- return 0;
+ return;
if (regs->msr & MSR_FP)
giveup_fpu(current);
- memcpy(fpregs, ¤t->thread.fpr[0], sizeof(*fpregs));
+}
+
+void dump_smp_unlazy_fpu(void)
+{
+ smp_call_function(smp_unlazy_onefpu, NULL, 1, 1);
+}
+#endif
+
+int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
+{
+ struct pt_regs *regs = tsk->thread.regs;
+
+ if (!regs)
+ return 0;
+ if (tsk == current && (regs->msr & MSR_FP))
+ giveup_fpu(current);
+
+ memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs));
+
return 1;
}
@@ -113,7 +130,7 @@
}
static void show_tsk_stack(struct task_struct *p, unsigned long sp);
-static char *ppc_find_proc_name(unsigned *p, char *buf, unsigned buflen);
+char *ppc_find_proc_name(unsigned *p, char *buf, unsigned buflen);
void show_regs(struct pt_regs * regs)
{
@@ -300,7 +317,6 @@
unsigned long p4, unsigned long p5, unsigned long p6,
struct pt_regs *regs)
{
- struct task_struct *p;
unsigned long parent_tidptr = 0;
unsigned long child_tidptr = 0;
@@ -320,36 +336,29 @@
if (regs->msr & MSR_FP)
giveup_fpu(current);
- p = do_fork(clone_flags & ~CLONE_IDLETASK, p2, regs, 0,
+ return do_fork(clone_flags & ~CLONE_IDLETASK, p2, regs, 0,
(int *)parent_tidptr, (int *)child_tidptr);
- return IS_ERR(p) ? PTR_ERR(p) : p->pid;
}
int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
unsigned long p4, unsigned long p5, unsigned long p6,
struct pt_regs *regs)
{
- struct task_struct *p;
-
if (regs->msr & MSR_FP)
giveup_fpu(current);
- p = do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL);
- return IS_ERR(p) ? PTR_ERR(p) : p->pid;
+ return do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL);
}
int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
unsigned long p4, unsigned long p5, unsigned long p6,
struct pt_regs *regs)
{
- struct task_struct *p;
-
if (regs->msr & MSR_FP)
giveup_fpu(current);
- p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1], regs, 0,
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1], regs, 0,
NULL, NULL);
- return IS_ERR(p) ? PTR_ERR(p) : p->pid;
}
int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
@@ -404,7 +413,7 @@
* __get_free_pages() might give us a page > KERNBASE+256M which
* is mapped with large ptes so we can't set up the guard page.
*/
- if (cpu_has_largepage())
+ if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE)
return;
for (i=0; i < NR_CPUS; i++) {
@@ -418,7 +427,7 @@
extern char _stext[], _etext[], __init_begin[], __init_end[];
-static char *ppc_find_proc_name(unsigned *p, char *buf, unsigned buflen)
+char *ppc_find_proc_name(unsigned *p, char *buf, unsigned buflen)
{
unsigned long tb_flags;
unsigned short name_len;
diff -Nru a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
--- a/arch/ppc64/kernel/prom.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/prom.c Thu Jun 19 00:45:34 2003
@@ -1120,7 +1120,7 @@
_prom->cpu = (int)(unsigned long)getprop_rval;
_xPaca[_prom->cpu].active = 1;
#ifdef CONFIG_SMP
- RELOC(cpu_online_map) = 1 << _prom->cpu;
+ RELOC(cpu_online_map) = 1UL << _prom->cpu;
#endif
RELOC(boot_cpuid) = _prom->cpu;
diff -Nru a/arch/ppc64/kernel/ras.c b/arch/ppc64/kernel/ras.c
--- a/arch/ppc64/kernel/ras.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/ras.c Thu Jun 19 00:45:34 2003
@@ -56,7 +56,6 @@
static void ras_epow_interrupt(int irq, void *dev_id, struct pt_regs * regs);
static void ras_error_interrupt(int irq, void *dev_id, struct pt_regs * regs);
-void init_ras_IRQ(void);
/* #define DEBUG */
@@ -64,7 +63,8 @@
* Initialize handlers for the set of interrupts caused by hardware errors
* and power system events.
*/
-void init_ras_IRQ(void) {
+static int __init init_ras_IRQ(void)
+{
struct device_node *np;
unsigned int *ireg, len, i;
@@ -89,7 +89,10 @@
ireg++;
}
}
+
+ return 1;
}
+__initcall(init_ras_IRQ);
/*
* Handle power subsystem events (EPOW).
diff -Nru a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c
--- a/arch/ppc64/kernel/setup.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/setup.c Thu Jun 19 00:45:34 2003
@@ -142,9 +142,6 @@
void setup_system(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
{
- /* This should be fixed properly in kernel/resource.c */
- iomem_resource.end = MEM_SPACE_LIMIT;
-
#ifdef CONFIG_XMON_DEFAULT
debugger = xmon;
debugger_bpt = xmon_bpt;
@@ -156,10 +153,10 @@
#ifdef CONFIG_PPC_ISERIES
/* pSeries systems are identified in prom.c via OF. */
if ( itLpNaca.xLparInstalled == 1 )
- naca->platform = PLATFORM_ISERIES_LPAR;
+ systemcfg->platform = PLATFORM_ISERIES_LPAR;
#endif
- switch (naca->platform) {
+ switch (systemcfg->platform) {
#ifdef CONFIG_PPC_ISERIES
case PLATFORM_ISERIES_LPAR:
iSeries_init_early();
@@ -185,7 +182,7 @@
#endif
}
- if (naca->platform & PLATFORM_PSERIES) {
+ if (systemcfg->platform & PLATFORM_PSERIES) {
early_console_initialized = 1;
register_console(&udbg_console);
}
@@ -193,32 +190,27 @@
printk("Starting Linux PPC64 %s\n", UTS_RELEASE);
printk("-----------------------------------------------------\n");
- printk("naca = 0x%p\n", naca);
-#if 0
- printk("naca->processorCount = 0x%x\n", naca->processorCount);
-#endif
- printk("naca->physicalMemorySize = 0x%lx\n", naca->physicalMemorySize);
- printk("naca->dCacheL1LineSize = 0x%x\n", naca->dCacheL1LineSize);
- printk("naca->dCacheL1LogLineSize = 0x%x\n", naca->dCacheL1LogLineSize);
- printk("naca->dCacheL1LinesPerPage = 0x%x\n", naca->dCacheL1LinesPerPage);
- printk("naca->iCacheL1LineSize = 0x%x\n", naca->iCacheL1LineSize);
- printk("naca->iCacheL1LogLineSize = 0x%x\n", naca->iCacheL1LogLineSize);
- printk("naca->iCacheL1LinesPerPage = 0x%x\n", naca->iCacheL1LinesPerPage);
- printk("naca->pftSize = 0x%lx\n", naca->pftSize);
- printk("naca->debug_switch = 0x%lx\n", naca->debug_switch);
- printk("naca->interrupt_controller = 0x%d\n", naca->interrupt_controller);
- printk("htab_data.htab = 0x%p\n", htab_data.htab);
- printk("htab_data.num_ptegs = 0x%lx\n", htab_data.htab_num_ptegs);
+ printk("naca = 0x%p\n", naca);
+ printk("naca->pftSize = 0x%lx\n", naca->pftSize);
+ printk("naca->debug_switch = 0x%lx\n", naca->debug_switch);
+ printk("naca->interrupt_controller = 0x%ld\n", naca->interrupt_controller);
+ printk("systemcfg = 0x%p\n", systemcfg);
+ printk("systemcfg->processorCount = 0x%lx\n", systemcfg->processorCount);
+ printk("systemcfg->physicalMemorySize = 0x%lx\n", systemcfg->physicalMemorySize);
+ printk("systemcfg->dCacheL1LineSize = 0x%x\n", systemcfg->dCacheL1LineSize);
+ printk("systemcfg->iCacheL1LineSize = 0x%x\n", systemcfg->iCacheL1LineSize);
+ printk("htab_data.htab = 0x%p\n", htab_data.htab);
+ printk("htab_data.num_ptegs = 0x%lx\n", htab_data.htab_num_ptegs);
printk("-----------------------------------------------------\n");
- if (naca->platform & PLATFORM_PSERIES) {
+ if (systemcfg->platform & PLATFORM_PSERIES) {
finish_device_tree();
chrp_init(r3, r4, r5, r6, r7);
}
mm_init_ppc64();
- switch (naca->platform) {
+ switch (systemcfg->platform) {
#ifdef CONFIG_PPC_ISERIES
case PLATFORM_ISERIES_LPAR:
iSeries_init();
@@ -264,7 +256,7 @@
return 0;
}
- if (!(cpu_online_map & (1<<cpu_id)))
+ if (!(cpu_online_map & (1UL << cpu_id)))
return 0;
#ifdef CONFIG_SMP
@@ -312,7 +304,7 @@
* Assume here that all clock rates are the same in a
* smp system. -- Cort
*/
- if (naca->platform != PLATFORM_ISERIES_LPAR) {
+ if (systemcfg->platform != PLATFORM_ISERIES_LPAR) {
struct device_node *cpu_node;
int *fp;
@@ -373,16 +365,15 @@
cmd_line[0] = 0;
#ifdef CONFIG_CMDLINE
- strcpy(cmd_line, CONFIG_CMDLINE);
+ strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line));
#endif /* CONFIG_CMDLINE */
chosen = find_devices("chosen");
if (chosen != NULL) {
p = get_property(chosen, "bootargs", NULL);
if (p != NULL && p[0] != 0)
- strncpy(cmd_line, p, sizeof(cmd_line));
+ strlcpy(cmd_line, p, sizeof(cmd_line));
}
- cmd_line[sizeof(cmd_line) - 1] = 0;
/* Look for mem= option on command line */
if (strstr(cmd_line, "mem=")) {
@@ -516,8 +507,8 @@
* Systems with OF can look in the properties on the cpu node(s)
* for a possibly more accurate value.
*/
- dcache_bsize = naca->dCacheL1LineSize;
- icache_bsize = naca->iCacheL1LineSize;
+ dcache_bsize = systemcfg->dCacheL1LineSize;
+ icache_bsize = systemcfg->iCacheL1LineSize;
/* reboot on panic */
panic_timeout = 180;
@@ -593,7 +584,7 @@
/* The parameter is the number of processors to share in processing lp events */
unsigned long i;
unsigned long val = simple_strtoul( str, NULL, 0 );
- if ( ( val > 0 ) && ( val <= MAX_PACAS ) ) {
+ if ( ( val > 0 ) && ( val <= NR_CPUS ) ) {
for ( i=1; i<val; ++i )
paca[i].lpQueuePtr = paca[0].lpQueuePtr;
printk("lpevent processing spread over %ld processors\n", val);
diff -Nru a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c
--- a/arch/ppc64/kernel/signal.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/signal.c Thu Jun 19 00:45:34 2003
@@ -43,98 +43,37 @@
#endif
#define GP_REGS_SIZE MIN(sizeof(elf_gregset_t), sizeof(struct pt_regs))
+#define FP_REGS_SIZE sizeof(elf_fpregset_t)
-/*
- * These are the flags in the MSR that the user is allowed to change
- * by modifying the saved value of the MSR on the stack. SE and BE
- * should not be in this list since gdb may want to change these. I.e,
- * you should be able to step out of a signal handler to see what
- * instruction executes next after the signal handler completes.
- * Alternately, if you stepped into a signal handler, you should be
- * able to continue 'til the next breakpoint from within the signal
- * handler, even if the handler returns.
- */
-#if 0
-#define MSR_USERCHANGE (MSR_FE0 | MSR_FE1)
-#else
-/*
- * glibc tries to set FE0/FE1 via a signal handler. Since it only ever
- * sets both bits and this is the default setting we now disable this
- * behaviour. This is done to insure the new prctl which alters FE0/FE1 does
- * not get overriden by glibc. Setting and clearing FE0/FE1 via signal
- * handler has always been bogus since load_up_fpu used to set FE0/FE1
- * unconditionally.
- */
-#define MSR_USERCHANGE 0
-#endif
+#define TRAMP_TRACEBACK 3
+#define TRAMP_SIZE 6
/*
- * When we have signals to deliver, we set up on the
- * user stack, going down from the original stack pointer:
- * a sigregs struct
- * one or more sigcontext structs with
- * a gap of __SIGNAL_FRAMESIZE bytes
- *
- * Each of these things must be a multiple of 16 bytes in size.
- *
+ * When we have signals to deliver, we set up on the user stack,
+ * going down from the original stack pointer:
+ * 1) a rt_sigframe struct which contains the ucontext
+ * 2) a gap of __SIGNAL_FRAMESIZE bytes which acts as a dummy caller
+ * frame for the signal handler.
*/
-struct sigregs {
- elf_gregset_t gp_regs;
- double fp_regs[ELF_NFPREG];
- unsigned int tramp[2];
- /* 64 bit API allows for 288 bytes below sp before
- decrementing it. */
- int abigap[72];
-};
-struct rt_sigframe
-{
- unsigned long _unused[2];
+struct rt_sigframe {
+ /* sys_rt_sigreturn requires the ucontext be the first field */
+ struct ucontext uc;
+ unsigned long _unused[2];
+ unsigned int tramp[TRAMP_SIZE];
struct siginfo *pinfo;
void *puc;
struct siginfo info;
- struct ucontext uc;
+ /* 64 bit ABI allows for 288 bytes below sp before decrementing it. */
+ char abigap[288];
};
-extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
-
/*
* Atomically swap in the new signal mask, and wait for a signal.
*/
-long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
- struct pt_regs *regs)
-{
- sigset_t saveset;
-
- mask &= _BLOCKABLE;
- spin_lock_irq(¤t->sighand->siglock);
- saveset = current->blocked;
- siginitset(¤t->blocked, mask);
- recalc_sigpending();
- spin_unlock_irq(¤t->sighand->siglock);
-
- regs->result = -EINTR;
- regs->gpr[3] = EINTR;
- regs->ccr |= 0x10000000;
- while (1) {
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- if (do_signal(&saveset, regs))
- /*
- * If a signal handler needs to be called,
- * do_signal() has set R3 to the signal number (the
- * first argument of the signal handler), so don't
- * overwrite that with EINTR !
- * In the other cases, do_signal() doesn't touch
- * R3, so it's still set to -EINTR (see above).
- */
- return regs->gpr[3];
- }
-}
-
-long sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int p6,
- int p7, struct pt_regs *regs)
+long sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4,
+ int p6, int p7, struct pt_regs *regs)
{
sigset_t saveset, newset;
@@ -170,339 +109,232 @@
return do_sigaltstack(uss, uoss, regs->gpr[1]);
}
-long sys_sigaction(int sig, const struct old_sigaction *act,
- struct old_sigaction *oact)
+
+/*
+ * Set up the sigcontext for the signal frame.
+ */
+
+static int
+setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+ int signr, sigset_t *set, unsigned long handler)
{
- struct k_sigaction new_ka, old_ka;
- int ret;
+ int err = 0;
- if (act) {
- old_sigset_t mask;
+ if (regs->msr & MSR_FP)
+ giveup_fpu(current);
- if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
- __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
- __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
- return -EFAULT;
- __get_user(new_ka.sa.sa_flags, &act->sa_flags);
- __get_user(mask, &act->sa_mask);
- siginitset(&new_ka.sa.sa_mask, mask);
- }
+ current->thread.saved_msr = regs->msr & ~(MSR_FP | MSR_FE0 | MSR_FE1);
+ regs->msr = current->thread.saved_msr | current->thread.fpexc_mode;
+ current->thread.saved_softe = regs->softe;
+
+ err |= __put_user(&sc->gp_regs, &sc->regs);
+ err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE);
+ err |= __copy_to_user(&sc->fp_regs, ¤t->thread.fpr, FP_REGS_SIZE);
+ err |= __put_user(signr, &sc->signal);
+ err |= __put_user(handler, &sc->handler);
+ if (set != NULL)
+ err |= __put_user(set->sig[0], &sc->oldmask);
- ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
- if (!ret && oact) {
- if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
- __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
- __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
- return -EFAULT;
- __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
- __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
- }
+ regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
+ current->thread.fpscr = 0;
- return ret;
+ return err;
}
/*
- * When we have rt signals to deliver, we set up on the
- * user stack, going down from the original stack pointer:
- * a sigregs struct
- * one rt_sigframe struct (siginfo + ucontext)
- * a gap of __SIGNAL_FRAMESIZE bytes
- *
- * Each of these things must be a multiple of 16 bytes in size.
- *
+ * Restore the sigcontext from the signal frame.
*/
-int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
- unsigned long r6, unsigned long r7, unsigned long r8,
- struct pt_regs *regs)
+static int
+restore_sigcontext(struct pt_regs *regs, sigset_t *set, struct sigcontext *sc)
{
- struct rt_sigframe *rt_sf;
- struct sigcontext sigctx;
- struct sigregs *sr;
- elf_gregset_t saved_regs; /* an array of ELF_NGREG unsigned longs */
- sigset_t set;
- stack_t st;
+ unsigned int err = 0;
- rt_sf = (struct rt_sigframe *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
- if (copy_from_user(&sigctx, &rt_sf->uc.uc_mcontext, sizeof(sigctx))
- || copy_from_user(&set, &rt_sf->uc.uc_sigmask, sizeof(set))
- || copy_from_user(&st, &rt_sf->uc.uc_stack, sizeof(st)))
- goto badframe;
- sigdelsetmask(&set, ~_BLOCKABLE);
- spin_lock_irq(¤t->sighand->siglock);
- current->blocked = set;
- recalc_sigpending();
- spin_unlock_irq(¤t->sighand->siglock);
if (regs->msr & MSR_FP)
giveup_fpu(current);
- /* restore registers -
- * sigctx is initialized to point to the
- * preamble frame (where registers are stored)
- * see handle_signal()
- */
- sr = (struct sigregs *)sigctx.regs;
- if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs)))
- goto badframe;
- saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
- | (saved_regs[PT_MSR] & MSR_USERCHANGE);
- saved_regs[PT_SOFTE] = regs->softe;
- memcpy(regs, saved_regs, GP_REGS_SIZE);
- if (copy_from_user(current->thread.fpr, &sr->fp_regs,
- sizeof(sr->fp_regs)))
- goto badframe;
- /* This function sets back the stack flags into
- the current task structure. */
- sys_sigaltstack(&st, NULL, 0, 0, 0, 0, regs);
-
- return regs->result;
+ err |= __copy_from_user(regs, &sc->gp_regs, GP_REGS_SIZE);
+ err |= __copy_from_user(¤t->thread.fpr, &sc->fp_regs, FP_REGS_SIZE);
+ current->thread.fpexc_mode = regs->msr & (MSR_FE0 | MSR_FE1);
+ if (set != NULL)
+ err |= __get_user(set->sig[0], &sc->oldmask);
+
+ /* Don't allow the signal handler to change these modulo FE{0,1} */
+ regs->msr = current->thread.saved_msr & ~(MSR_FP | MSR_FE0 | MSR_FE1);
+ regs->softe = current->thread.saved_softe;
-badframe:
- do_exit(SIGSEGV);
+ return err;
}
-static void setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
- signed long newsp)
+/*
+ * Allocate space for the signal frame
+ */
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
{
- struct rt_sigframe *rt_sf = (struct rt_sigframe *)newsp;
- /* Handler is *really* a pointer to the function descriptor for
- * the signal routine. The first entry in the function
- * descriptor is the entry address of signal and the second
- * entry is the TOC value we need to use.
- */
- struct funct_descr_entry {
- unsigned long entry;
- unsigned long toc;
- };
-
- struct funct_descr_entry * funct_desc_ptr;
- unsigned long temp_ptr;
+ unsigned long newsp;
- /* Set up preamble frame */
- if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
- goto badframe;
- if (regs->msr & MSR_FP)
- giveup_fpu(current);
- if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
- || __copy_to_user(&frame->fp_regs, current->thread.fpr,
- ELF_NFPREG * sizeof(double))
- /* li r0, __NR_rt_sigreturn */
- || __put_user(0x38000000UL + __NR_rt_sigreturn, &frame->tramp[0])
- /* sc */
- || __put_user(0x44000002UL, &frame->tramp[1]))
- goto badframe;
- flush_icache_range((unsigned long)&frame->tramp[0],
- (unsigned long)&frame->tramp[2]);
- current->thread.fpscr = 0; /* turn off all fp exceptions */
-
- /* Retrieve rt_sigframe from stack and
- set up registers for signal handler
- */
- newsp -= __SIGNAL_FRAMESIZE;
+ /* Default to using normal stack */
+ newsp = regs->gpr[1];
- if (get_user(temp_ptr, &rt_sf->uc.uc_mcontext.handler)) {
- goto badframe;
+ if (ka->sa.sa_flags & SA_ONSTACK) {
+ if (! on_sig_stack(regs->gpr[1]))
+ newsp = (current->sas_ss_sp + current->sas_ss_size);
}
- funct_desc_ptr = (struct funct_descr_entry *)temp_ptr;
-
- if (put_user(regs->gpr[1], (unsigned long *)newsp)
- || get_user(regs->nip, &funct_desc_ptr->entry)
- || get_user(regs->gpr[2], &funct_desc_ptr->toc)
- || get_user(regs->gpr[3], &rt_sf->uc.uc_mcontext.signal)
- || get_user(regs->gpr[4], (unsigned long *)&rt_sf->pinfo)
- || get_user(regs->gpr[5], (unsigned long *)&rt_sf->puc))
- goto badframe;
+ return (void *)((newsp - frame_size) & -8ul);
+}
- regs->gpr[1] = newsp;
- regs->gpr[6] = (unsigned long)rt_sf;
- regs->link = (unsigned long)frame->tramp;
+static int
+setup_trampoline(unsigned int syscall, unsigned int *tramp)
+{
+ int i, err = 0;
- return;
+ /* addi r1, r1, __SIGNAL_FRAMESIZE # Pop the dummy stackframe */
+ err |= __put_user(0x38210000UL | (__SIGNAL_FRAMESIZE & 0xffff), &tramp[0]);
+ /* li r0, __NR_[rt_]sigreturn| */
+ err |= __put_user(0x38000000UL | (syscall & 0xffff), &tramp[1]);
+ /* sc */
+ err |= __put_user(0x44000002UL, &tramp[2]);
+
+ /* Minimal traceback info */
+ for (i=TRAMP_TRACEBACK; i < TRAMP_SIZE ;i++)
+ err |= __put_user(0, &tramp[i]);
+
+ if (!err)
+ flush_icache_range((unsigned long) &tramp[0],
+ (unsigned long) &tramp[TRAMP_SIZE]);
-badframe:
-#if DEBUG_SIG
- printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n",
- regs, frame, newsp);
-#endif
- do_exit(SIGSEGV);
+ return err;
}
/*
* Do a signal return; undo the signal stack.
*/
-long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
- unsigned long r6, unsigned long r7, unsigned long r8,
- struct pt_regs *regs)
-{
- struct sigcontext *sc, sigctx;
- struct sigregs *sr;
- elf_gregset_t saved_regs; /* an array of ELF_NGREG unsigned longs */
+
+int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7, unsigned long r8,
+ struct pt_regs *regs)
+{
+ struct ucontext *uc = (struct ucontext *)regs->gpr[1];
sigset_t set;
+ stack_t st;
- sc = (struct sigcontext *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
- if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
+ if (verify_area(VERIFY_READ, uc, sizeof(*uc)))
goto badframe;
- set.sig[0] = sigctx.oldmask;
-#if _NSIG_WORDS > 1
- set.sig[1] = sigctx._unused[3];
-#endif
+ if (__copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
+ goto badframe;
sigdelsetmask(&set, ~_BLOCKABLE);
spin_lock_irq(¤t->sighand->siglock);
current->blocked = set;
recalc_sigpending();
spin_unlock_irq(¤t->sighand->siglock);
- if (regs->msr & MSR_FP)
- giveup_fpu(current);
- /* restore registers */
- sr = (struct sigregs *)sigctx.regs;
- if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs)))
+ if (restore_sigcontext(regs, NULL, &uc->uc_mcontext))
goto badframe;
- saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
- | (saved_regs[PT_MSR] & MSR_USERCHANGE);
- saved_regs[PT_SOFTE] = regs->softe;
- memcpy(regs, saved_regs, GP_REGS_SIZE);
- if (copy_from_user(current->thread.fpr, &sr->fp_regs,
- sizeof(sr->fp_regs)))
+ if (__copy_from_user(&st, &uc->uc_stack, sizeof(st)))
goto badframe;
+ /* This function sets back the stack flags into
+ the current task structure. */
+ sys_sigaltstack(&st, NULL, 0, 0, 0, 0, regs);
return regs->result;
badframe:
+#if DEBUG_SIG
+ printk("badframe in sys_rt_sigreturn, regs=%p uc=%p &uc->uc_mcontext=%p\n",
+ regs, uc, &uc->uc_mcontext);
+#endif
do_exit(SIGSEGV);
-}
+}
-/*
- * Set up a signal frame.
- */
-static void setup_frame(struct pt_regs *regs, struct sigregs *frame,
- unsigned long newsp)
+static void
+setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
+ sigset_t *set, struct pt_regs *regs)
{
-
/* Handler is *really* a pointer to the function descriptor for
* the signal routine. The first entry in the function
* descriptor is the entry address of signal and the second
* entry is the TOC value we need to use.
*/
- struct funct_descr_entry {
- unsigned long entry;
- unsigned long toc;
- };
-
- struct funct_descr_entry * funct_desc_ptr;
- unsigned long temp_ptr;
+ func_descr_t *funct_desc_ptr;
+ struct rt_sigframe *frame;
+ unsigned long newsp = 0;
+ int err = 0;
- struct sigcontext *sc = (struct sigcontext *)newsp;
-
- if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
- goto badframe;
- if (regs->msr & MSR_FP)
- giveup_fpu(current);
- if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
- || __copy_to_user(&frame->fp_regs, current->thread.fpr,
- ELF_NFPREG * sizeof(double))
- /* li r0, __NR_sigreturn */
- || __put_user(0x38000000UL + __NR_sigreturn, &frame->tramp[0])
- /* sc */
- || __put_user(0x44000002UL, &frame->tramp[1]))
- goto badframe;
- flush_icache_range((unsigned long)&frame->tramp[0],
- (unsigned long)&frame->tramp[2]);
- current->thread.fpscr = 0; /* turn off all fp exceptions */
+ frame = get_sigframe(ka, regs, sizeof(*frame));
- newsp -= __SIGNAL_FRAMESIZE;
- if (get_user(temp_ptr, &sc->handler))
+ if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
goto badframe;
-
- funct_desc_ptr = (struct funct_descr_entry *)temp_ptr;
- if (put_user(regs->gpr[1], (unsigned long *)newsp)
- || get_user(regs->nip, &funct_desc_ptr ->entry)
- || get_user(regs->gpr[2],&funct_desc_ptr->toc)
- || get_user(regs->gpr[3], &sc->signal))
- goto badframe;
+ err |= __put_user(&frame->info, &frame->pinfo);
+ err |= __put_user(&frame->uc, &frame->puc);
+ err |= copy_siginfo_to_user(&frame->info, info);
+ if (err)
+ goto badframe;
+
+ /* Create the ucontext. */
+ err |= __put_user(0, &frame->uc.uc_flags);
+ err |= __put_user(0, &frame->uc.uc_link);
+ err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
+ err |= __put_user(sas_ss_flags(regs->gpr[1]),
+ &frame->uc.uc_stack.ss_flags);
+ err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+ err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, signr, NULL,
+ (unsigned long)ka->sa.sa_handler);
+ err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+ if (err)
+ goto badframe;
+
+ /* Set up to return from userspace. */
+ err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
+ if (err)
+ goto badframe;
+
+ funct_desc_ptr = (func_descr_t *) ka->sa.sa_handler;
+
+ /* Allocate a dummy caller frame for the signal handler. */
+ newsp = (unsigned long)frame - __SIGNAL_FRAMESIZE;
+ err |= put_user(0, (unsigned long *)newsp);
+
+ /* Set up "regs" so we "return" to the signal handler. */
+ err |= get_user(regs->nip, &funct_desc_ptr->entry);
+ regs->link = (unsigned long) &frame->tramp[0];
regs->gpr[1] = newsp;
- regs->gpr[4] = (unsigned long)sc;
- regs->link = (unsigned long)frame->tramp;
+ err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
+ regs->gpr[3] = signr;
+ if (ka->sa.sa_flags & SA_SIGINFO) {
+ err |= get_user(regs->gpr[4], (unsigned long *)&frame->pinfo);
+ err |= get_user(regs->gpr[5], (unsigned long *)&frame->puc);
+ regs->gpr[6] = (unsigned long) frame;
+ } else {
+ regs->gpr[4] = (unsigned long)&frame->uc.uc_mcontext;
+ }
+ if (err)
+ goto badframe;
return;
badframe:
#if DEBUG_SIG
- printk("badframe in setup_frame, regs=%p frame=%p newsp=%lx\n",
+ printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n",
regs, frame, newsp);
#endif
do_exit(SIGSEGV);
}
+
/*
* OK, we're invoking a handler
*/
-static void handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
- struct pt_regs * regs, unsigned long *newspp, unsigned long frame)
+static void
+handle_signal(unsigned long sig, struct k_sigaction *ka,
+ siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
{
- struct sigcontext *sc;
- struct rt_sigframe *rt_sf;
- struct k_sigaction *ka = ¤t->sighand->action[sig-1];
-
- if (regs->trap == 0x0C00 /* System Call! */
- && ((int)regs->result == -ERESTARTNOHAND ||
- (int)regs->result == -ERESTART_RESTARTBLOCK ||
- ((int)regs->result == -ERESTARTSYS &&
- !(ka->sa.sa_flags & SA_RESTART)))) {
- if ((int)regs->result == -ERESTART_RESTARTBLOCK)
- current_thread_info()->restart_block.fn
- = do_no_restart_syscall;
- regs->result = -EINTR;
- }
-
/* Set up Signal Frame */
- if (ka->sa.sa_flags & SA_SIGINFO) {
- /* Put a Real Time Context onto stack */
- *newspp -= sizeof(*rt_sf);
- rt_sf = (struct rt_sigframe *)*newspp;
- if (verify_area(VERIFY_WRITE, rt_sf, sizeof(*rt_sf)))
- goto badframe;
-
- if (__put_user((unsigned long)ka->sa.sa_handler,
- &rt_sf->uc.uc_mcontext.handler)
- || __put_user(&rt_sf->info, &rt_sf->pinfo)
- || __put_user(&rt_sf->uc, &rt_sf->puc)
- /* Put the siginfo */
- || copy_siginfo_to_user(&rt_sf->info, info)
- /* Create the ucontext */
- || __put_user(0, &rt_sf->uc.uc_flags)
- || __put_user(0, &rt_sf->uc.uc_link)
- || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
- || __put_user(sas_ss_flags(regs->gpr[1]),
- &rt_sf->uc.uc_stack.ss_flags)
- || __put_user(current->sas_ss_size,
- &rt_sf->uc.uc_stack.ss_size)
- || __copy_to_user(&rt_sf->uc.uc_sigmask,
- oldset, sizeof(*oldset))
- /* mcontext.regs points to preamble register frame */
- || __put_user((struct pt_regs *)frame, &rt_sf->uc.uc_mcontext.regs)
- || __put_user(sig, &rt_sf->uc.uc_mcontext.signal))
- goto badframe;
- } else {
- /* Put a sigcontext on the stack */
- *newspp -= sizeof(*sc);
- sc = (struct sigcontext *)*newspp;
- if (verify_area(VERIFY_WRITE, sc, sizeof(*sc)))
- goto badframe;
-
- if (__put_user((unsigned long)ka->sa.sa_handler, &sc->handler)
- || __put_user(oldset->sig[0], &sc->oldmask)
-#if _NSIG_WORDS > 1
- || __put_user(oldset->sig[1], &sc->_unused[3])
-#endif
- || __put_user((struct pt_regs *)frame, &sc->regs)
- || __put_user(sig, &sc->signal))
- goto badframe;
- }
+ setup_rt_frame(sig, ka, info, oldset, regs);
if (ka->sa.sa_flags & SA_ONESHOT)
ka->sa.sa_handler = SIG_DFL;
@@ -515,14 +347,40 @@
spin_unlock_irq(¤t->sighand->siglock);
}
return;
+}
-badframe:
-#if DEBUG_SIG
- printk("badframe in handle_signal, regs=%p frame=%lx newsp=%lx\n",
- regs, frame, *newspp);
- printk("sc=%p sig=%d ka=%p info=%p oldset=%p\n", sc, sig, ka, info, oldset);
-#endif
- do_exit(SIGSEGV);
+static inline void
+syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
+{
+ switch ((int)regs->result) {
+ case -ERESTART_RESTARTBLOCK:
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+ /* fallthrough */
+ case -ERESTARTNOHAND:
+ /* ERESTARTNOHAND means that the syscall should only be
+ * restarted if there was no handler for the signal, and since
+ * we only get here if there is a handler, we dont restart.
+ */
+ regs->result = -EINTR;
+ break;
+ case -ERESTARTSYS:
+ /* ERESTARTSYS means to restart the syscall if there is no
+ * handler or the handler was registered with SA_RESTART
+ */
+ if (!(ka->sa.sa_flags & SA_RESTART)) {
+ regs->result = -EINTR;
+ break;
+ }
+ /* fallthrough */
+ case -ERESTARTNOINTR:
+ /* ERESTARTNOINTR means that the syscall should be
+ * called again after the signal handler returns.
+ */
+ regs->gpr[3] = regs->orig_gpr3;
+ regs->nip -= 4;
+ regs->result = 0;
+ break;
+ }
}
/*
@@ -530,13 +388,9 @@
* want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake.
*/
-extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
-
int do_signal(sigset_t *oldset, struct pt_regs *regs)
{
siginfo_t info;
- struct k_sigaction *ka;
- unsigned long frame, newsp;
int signr;
/*
@@ -549,20 +403,15 @@
if (!oldset)
oldset = ¤t->blocked;
- newsp = frame = 0;
-
signr = get_signal_to_deliver(&info, regs, NULL);
if (signr > 0) {
- ka = ¤t->sighand->action[signr-1];
- if ((ka->sa.sa_flags & SA_ONSTACK)
- && (!on_sig_stack(regs->gpr[1])))
- newsp = (current->sas_ss_sp + current->sas_ss_size);
- else
- newsp = regs->gpr[1];
- newsp = frame = newsp - sizeof(struct sigregs);
+ struct k_sigaction *ka = ¤t->sighand->action[signr-1];
/* Whee! Actually deliver the signal. */
- handle_signal(signr, &info, oldset, regs, &newsp, frame);
+ if (regs->trap == 0x0C00)
+ syscall_restart(regs, ka);
+ handle_signal(signr, ka, &info, oldset, regs);
+ return 1;
}
if (regs->trap == 0x0C00) { /* System Call! */
@@ -579,13 +428,8 @@
}
}
- if (newsp == frame)
- return 0; /* no signals delivered */
-
- /* Invoke correct stack setup routine */
- if (ka->sa.sa_flags & SA_SIGINFO)
- setup_rt_frame(regs, (struct sigregs *)frame, newsp);
- else
- setup_frame(regs, (struct sigregs *)frame, newsp);
- return 1;
+ return 0;
}
+
+
+
diff -Nru a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c
--- a/arch/ppc64/kernel/signal32.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/signal32.c Thu Jun 19 00:45:34 2003
@@ -529,10 +529,6 @@
return ret;
}
-
-extern long sys_rt_sigprocmask(int how, sigset_t *set,
- sigset_t *oset, size_t sigsetsize);
-
/*
* Note: it is necessary to treat how as an unsigned int, with the
* corresponding cast to a signed int to insure that the proper
@@ -579,10 +575,6 @@
return 0;
}
-
-extern long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
-
-
long sys32_rt_sigpending(compat_sigset_t *set, compat_size_t sigsetsize)
{
sigset_t s;
@@ -649,11 +641,6 @@
return err;
}
-
-extern long sys_rt_sigtimedwait(const sigset_t *uthese,
- siginfo_t *uinfo, const struct timespec *uts,
- size_t sigsetsize);
-
long sys32_rt_sigtimedwait(compat_sigset_t *uthese, siginfo_t32 *uinfo,
struct compat_timespec *uts, compat_size_t sigsetsize)
{
@@ -724,9 +711,6 @@
return d;
}
-
-extern long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
-
/*
* Note: it is necessary to treat pid and sig as unsigned ints, with the
* corresponding cast to a signed int to insure that the proper conversion
@@ -751,8 +735,6 @@
set_fs (old_fs);
return ret;
}
-
-extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
int sys32_rt_sigsuspend(compat_sigset_t* unewset, size_t sigsetsize, int p3,
int p4, int p6, int p7, struct pt_regs *regs)
diff -Nru a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c
--- a/arch/ppc64/kernel/smp.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/smp.c Thu Jun 19 00:45:34 2003
@@ -46,8 +46,10 @@
#include <asm/ppcdebug.h>
#include "open_pic.h"
#include <asm/machdep.h>
+#include <asm/xics.h>
+#include <asm/cputable.h>
-int smp_threads_ready = 0;
+int smp_threads_ready;
unsigned long cache_decay_ticks;
/* initialised so it doesn't end up in bss */
@@ -63,18 +65,6 @@
void smp_call_function_interrupt(void);
void smp_message_pass(int target, int msg, unsigned long data, int wait);
-void xics_setup_cpu(void);
-void xics_cause_IPI(int cpu);
-
-/*
- * XICS only has a single IPI, so encode the messages per CPU
- */
-struct xics_ipi_struct {
- volatile unsigned long value;
-} ____cacheline_aligned;
-
-struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
-
#define smp_message_pass(t,m,d,w) smp_ops->message_pass((t),(m),(d),(w))
static inline void set_tb(unsigned int upper, unsigned int lower)
@@ -124,7 +114,7 @@
struct ItLpPaca * lpPaca;
np = 0;
- for (i=0; i < MAX_PACAS; ++i) {
+ for (i=0; i < NR_CPUS; ++i) {
lpPaca = paca[i].xLpPacaPtr;
if ( lpPaca->xDynProcStatus < 2 ) {
++np;
@@ -139,7 +129,7 @@
unsigned np = 0;
struct ItLpPaca *lpPaca;
- for (i=0; i < MAX_PACAS; ++i) {
+ for (i=0; i < NR_CPUS; ++i) {
lpPaca = paca[i].xLpPacaPtr;
if (lpPaca->xDynProcStatus < 2) {
paca[i].active = 1;
@@ -155,7 +145,7 @@
struct ItLpPaca * lpPaca;
/* Verify we have a Paca for processor nr */
if ( ( nr <= 0 ) ||
- ( nr >= MAX_PACAS ) )
+ ( nr >= NR_CPUS ) )
return;
/* Verify that our partition has a processor nr */
lpPaca = paca[nr].xLpPacaPtr;
@@ -189,7 +179,7 @@
smp_ops->kick_cpu = smp_iSeries_kick_cpu;
smp_ops->setup_cpu = smp_iSeries_setup_cpu;
#warning fix for iseries
- naca->processorCount = smp_iSeries_numProcs();
+ systemcfg->processorCount = smp_iSeries_numProcs();
}
#endif
@@ -239,7 +229,7 @@
{
/* Verify we have a Paca for processor nr */
if ( ( nr <= 0 ) ||
- ( nr >= MAX_PACAS ) )
+ ( nr >= NR_CPUS ) )
return;
/* The information for processor bringup must
@@ -353,7 +343,7 @@
smp_ops->probe = smp_xics_probe;
}
- if (naca->platform == PLATFORM_PSERIES) {
+ if (systemcfg->platform == PLATFORM_PSERIES) {
smp_ops->give_timebase = pSeries_give_timebase;
smp_ops->take_timebase = pSeries_take_timebase;
}
@@ -403,17 +393,6 @@
smp_message_pass(cpu, PPC_MSG_RESCHEDULE, 0, 0);
}
-/*
- * this function sends a reschedule IPI to all (other) CPUs.
- * This should only be used if some 'global' task became runnable,
- * such as a RT task, that must be handled now. The first CPU
- * that manages to grab the task will run it.
- */
-void smp_send_reschedule_all(void)
-{
- smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_RESCHEDULE, 0, 0);
-}
-
#ifdef CONFIG_XMON
void smp_send_xmon_break(int cpu)
{
@@ -605,7 +584,7 @@
paca[cpu].prof_multiplier = 1;
paca[cpu].default_decr = tb_ticks_per_jiffy / decr_overclock;
- if (!cpu_has_slb()) {
+ if (!(cur_cpu_spec->cpu_features & CPU_FTR_SLB)) {
void *tmp;
/* maximum of 48 CPUs on machines with a segment table */
@@ -621,10 +600,11 @@
/* create a process for the processor */
/* only regs.msr is actually used, and 0 is OK for it */
memset(®s, 0, sizeof(struct pt_regs));
- p = do_fork(CLONE_VM|CLONE_IDLETASK, 0, ®s, 0, NULL, NULL);
+ p = copy_process(CLONE_VM|CLONE_IDLETASK, 0, ®s, 0, NULL, NULL);
if (IS_ERR(p))
panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
+ wake_up_forked_process(p);
init_idle(p, cpu);
unhash_process(p);
diff -Nru a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
--- a/arch/ppc64/kernel/sys_ppc32.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/sys_ppc32.c Thu Jun 19 00:45:34 2003
@@ -1829,7 +1829,7 @@
err = do_sys32_shmctl(first, second, (void *)AA(ptr));
break;
default:
- err = -ENOSYS;
+ err = -EINVAL;
break;
}
return err;
diff -Nru a/arch/ppc64/kernel/syscalls.c b/arch/ppc64/kernel/syscalls.c
--- a/arch/ppc64/kernel/syscalls.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/syscalls.c Thu Jun 19 00:45:34 2003
@@ -50,11 +50,6 @@
{
}
-int sys_ioperm(unsigned long from, unsigned long num, int on)
-{
- return -EIO;
-}
-
/*
* sys_ipc() is the de-multiplexer for the SysV IPC calls..
*
diff -Nru a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c
--- a/arch/ppc64/kernel/traps.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/traps.c Thu Jun 19 00:45:34 2003
@@ -28,6 +28,7 @@
#include <linux/interrupt.h>
#include <linux/config.h>
#include <linux/init.h>
+#include <linux/module.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
@@ -55,14 +56,12 @@
* Trap & Exception support
*/
-/* Should we panic on bad kernel exceptions or try to recover */
-#undef PANIC_ON_ERROR
-
static spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
void die(const char *str, struct pt_regs *regs, long err)
{
static int die_counter;
+
console_verbose();
spin_lock_irq(&die_lock);
bust_spinlocks(1);
@@ -71,11 +70,16 @@
bust_spinlocks(0);
spin_unlock_irq(&die_lock);
-#ifdef PANIC_ON_ERROR
- panic(str);
-#else
+ if (in_interrupt())
+ panic("Fatal exception in interrupt");
+
+ if (panic_on_oops) {
+ printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(5 * HZ);
+ panic("Fatal exception");
+ }
do_exit(SIGSEGV);
-#endif
}
static void
@@ -139,15 +143,13 @@
#ifdef CONFIG_DEBUG_KERNEL
if (debugger)
debugger(regs);
+ else
#endif
+ panic("System Reset");
-#ifdef PANIC_ON_ERROR
- panic("System Reset");
-#else
/* Must die if the interrupt is not recoverable */
if (!(regs->msr & MSR_RI))
panic("Unrecoverable System Reset");
-#endif
/* What should we do here? We could issue a shutdown or hard reset. */
}
@@ -305,6 +307,56 @@
_exception(SIGFPE, &info, regs);
}
+/*
+ * Look through the list of trap instructions that are used for BUG(),
+ * BUG_ON() and WARN_ON() and see if we hit one. At this point we know
+ * that the exception was caused by a trap instruction of some kind.
+ * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0
+ * otherwise.
+ */
+extern struct bug_entry __start___bug_table[], __stop___bug_table[];
+
+#ifndef CONFIG_MODULES
+#define module_find_bug(x) NULL
+#endif
+
+static struct bug_entry *find_bug(unsigned long bugaddr)
+{
+ struct bug_entry *bug;
+
+ for (bug = __start___bug_table; bug < __stop___bug_table; ++bug)
+ if (bugaddr == bug->bug_addr)
+ return bug;
+ return module_find_bug(bugaddr);
+}
+
+int
+check_bug_trap(struct pt_regs *regs)
+{
+ struct bug_entry *bug;
+ unsigned long addr;
+
+ if (regs->msr & MSR_PR)
+ return 0; /* not in kernel */
+ addr = regs->nip; /* address of trap instruction */
+ if (addr < PAGE_OFFSET)
+ return 0;
+ bug = find_bug(regs->nip);
+ if (bug == NULL)
+ return 0;
+ if (bug->line & BUG_WARNING_TRAP) {
+ /* this is a WARN_ON rather than BUG/BUG_ON */
+ printk(KERN_ERR "Badness in %s at %s:%d\n",
+ bug->function, bug->file,
+ bug->line & ~BUG_WARNING_TRAP);
+ dump_stack();
+ return 1;
+ }
+ printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
+ bug->function, bug->file, bug->line);
+ return 0;
+}
+
void
ProgramCheckException(struct pt_regs *regs)
{
@@ -329,6 +381,10 @@
if (debugger_bpt && debugger_bpt(regs))
return;
#endif
+ if (check_bug_trap(regs)) {
+ regs->nip += 4;
+ return;
+ }
info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = TRAP_BRKPT;
@@ -343,6 +399,14 @@
info.si_addr = (void *)regs->nip;
_exception(SIGILL, &info, regs);
}
+}
+
+void
+KernelFPUnavailableException(struct pt_regs *regs)
+{
+ printk("Illegal floating point used in kernel (task=0x%p, "
+ "pc=0x%016lx, trap=0x%lx)\n", current, regs->nip, regs->trap);
+ panic("Unrecoverable FP Unavailable Exception in Kernel");
}
void
diff -Nru a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c
--- a/arch/ppc64/kernel/xics.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/kernel/xics.c Thu Jun 19 00:45:34 2003
@@ -1,5 +1,5 @@
/*
- * arch/ppc/kernel/xics.c
+ * arch/ppc64/kernel/xics.c
*
* Copyright 2000 IBM Corporation.
*
@@ -22,11 +22,13 @@
#include <asm/smp.h>
#include <asm/naca.h>
#include <asm/rtas.h>
-#include "i8259.h"
#include <asm/xics.h>
#include <asm/ppcdebug.h>
+#include <asm/hvcall.h>
#include <asm/machdep.h>
+#include "i8259.h"
+
void xics_enable_irq(u_int irq);
void xics_disable_irq(u_int irq);
void xics_mask_and_ack_irq(u_int irq);
@@ -61,33 +63,39 @@
/* Want a priority other than 0. Various HW issues require this. */
#define DEFAULT_PRIORITY 5
+/*
+ * Mark IPIs as higher priority so we can take them inside interrupts that
+ * arent marked SA_INTERRUPT
+ */
+#define IPI_PRIORITY 4
+
struct xics_ipl {
union {
- u32 word;
- u8 bytes[4];
+ u32 word;
+ u8 bytes[4];
} xirr_poll;
union {
u32 word;
- u8 bytes[4];
+ u8 bytes[4];
} xirr;
- u32 dummy;
+ u32 dummy;
union {
- u32 word;
- u8 bytes[4];
+ u32 word;
+ u8 bytes[4];
} qirr;
};
-struct xics_info {
- volatile struct xics_ipl * per_cpu[NR_CPUS];
-};
+static struct xics_ipl *xics_per_cpu[NR_CPUS];
-struct xics_info xics_info;
+static int xics_irq_8259_cascade = 0;
+static int xics_irq_8259_cascade_real = 0;
+static unsigned int default_server = 0xFF;
+static unsigned int default_distrib_server = 0;
-unsigned long long intr_base = 0;
-int xics_irq_8259_cascade = 0;
-int xics_irq_8259_cascade_real = 0;
-unsigned int default_server = 0xFF;
-unsigned int default_distrib_server = 0;
+/*
+ * XICS only has a single IPI, so encode the messages per CPU
+ */
+struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
/* RTAS service tokens */
int ibm_get_xive;
@@ -95,11 +103,6 @@
int ibm_int_on;
int ibm_int_off;
-struct xics_interrupt_node {
- unsigned long long addr;
- unsigned long long size;
-} inodes[NR_CPUS*2];
-
typedef struct {
int (*xirr_info_get)(int cpu);
void (*xirr_info_set)(int cpu, int val);
@@ -108,24 +111,26 @@
} xics_ops;
+/* SMP */
+
static int pSeries_xirr_info_get(int n_cpu)
{
- return (xics_info.per_cpu[n_cpu]->xirr.word);
+ return xics_per_cpu[n_cpu]->xirr.word;
}
static void pSeries_xirr_info_set(int n_cpu, int value)
{
- xics_info.per_cpu[n_cpu]->xirr.word = value;
+ xics_per_cpu[n_cpu]->xirr.word = value;
}
static void pSeries_cppr_info(int n_cpu, u8 value)
{
- xics_info.per_cpu[n_cpu]->xirr.bytes[0] = value;
+ xics_per_cpu[n_cpu]->xirr.bytes[0] = value;
}
-static void pSeries_qirr_info(int n_cpu , u8 value)
+static void pSeries_qirr_info(int n_cpu, u8 value)
{
- xics_info.per_cpu[n_cpu]->qirr.bytes[0] = value;
+ xics_per_cpu[n_cpu]->qirr.bytes[0] = value;
}
static xics_ops pSeries_ops = {
@@ -136,113 +141,174 @@
};
static xics_ops *ops = &pSeries_ops;
-extern xics_ops pSeriesLP_ops;
-void
-xics_enable_irq(
- u_int virq
- )
+/* LPAR */
+
+static inline long plpar_eoi(unsigned long xirr)
{
- u_int irq;
- unsigned long status;
- long call_status;
+ return plpar_hcall_norets(H_EOI, xirr);
+}
+
+static inline long plpar_cppr(unsigned long cppr)
+{
+ return plpar_hcall_norets(H_CPPR, cppr);
+}
+
+static inline long plpar_ipi(unsigned long servernum, unsigned long mfrr)
+{
+ return plpar_hcall_norets(H_IPI, servernum, mfrr);
+}
+
+static inline long plpar_xirr(unsigned long *xirr_ret)
+{
+ unsigned long dummy;
+ return plpar_hcall(H_XIRR, 0, 0, 0, 0, xirr_ret, &dummy, &dummy);
+}
+
+static int pSeriesLP_xirr_info_get(int n_cpu)
+{
+ unsigned long lpar_rc;
+ unsigned long return_value;
+
+ lpar_rc = plpar_xirr(&return_value);
+ if (lpar_rc != H_Success)
+ panic(" bad return code xirr - rc = %lx \n", lpar_rc);
+ return (int)return_value;
+}
+
+static void pSeriesLP_xirr_info_set(int n_cpu, int value)
+{
+ unsigned long lpar_rc;
+ unsigned long val64 = value & 0xffffffff;
+
+ lpar_rc = plpar_eoi(val64);
+ if (lpar_rc != H_Success)
+ panic("bad return code EOI - rc = %ld, value=%lx\n", lpar_rc,
+ val64);
+}
+
+static void pSeriesLP_cppr_info(int n_cpu, u8 value)
+{
+ unsigned long lpar_rc;
+
+ lpar_rc = plpar_cppr(value);
+ if (lpar_rc != H_Success)
+ panic("bad return code cppr - rc = %lx\n", lpar_rc);
+}
+
+static void pSeriesLP_qirr_info(int n_cpu , u8 value)
+{
+ unsigned long lpar_rc;
+
+ lpar_rc = plpar_ipi(n_cpu, value);
+ if (lpar_rc != H_Success)
+ panic("bad return code qirr - rc = %lx\n", lpar_rc);
+}
+
+xics_ops pSeriesLP_ops = {
+ pSeriesLP_xirr_info_get,
+ pSeriesLP_xirr_info_set,
+ pSeriesLP_cppr_info,
+ pSeriesLP_qirr_info
+};
+
+void xics_enable_irq(u_int virq)
+{
+ u_int irq;
+ long call_status;
+ unsigned int server;
virq -= XICS_IRQ_OFFSET;
irq = virt_irq_to_real(virq);
if (irq == XICS_IPI)
return;
+
#ifdef CONFIG_IRQ_ALL_CPUS
- call_status = rtas_call(ibm_set_xive, 3, 1, (unsigned long*)&status,
- irq, smp_threads_ready ? default_distrib_server : default_server, DEFAULT_PRIORITY);
+ if (smp_threads_ready)
+ server = default_distrib_server;
+ else
+ server = default_server;
#else
- call_status = rtas_call(ibm_set_xive, 3, 1, (unsigned long*)&status,
- irq, default_server, DEFAULT_PRIORITY);
+ server = default_server;
#endif
- if( call_status != 0 ) {
- printk("xics_enable_irq: irq=%x: rtas_call failed; retn=%lx, status=%lx\n",
- irq, call_status, status);
+
+ call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server,
+ DEFAULT_PRIORITY);
+ if (call_status != 0) {
+ printk("xics_enable_irq: irq=%x: ibm_set_xive returned %lx\n",
+ irq, call_status);
return;
}
+
/* Now unmask the interrupt (often a no-op) */
- call_status = rtas_call(ibm_int_on, 1, 1, (unsigned long*)&status,
- irq);
- if( call_status != 0 ) {
- printk("xics_disable_irq on: irq=%x: rtas_call failed, retn=%lx\n",
+ call_status = rtas_call(ibm_int_on, 1, 1, NULL, irq);
+ if (call_status != 0) {
+ printk("xics_enable_irq: irq=%x: ibm_int_on returned %lx\n",
irq, call_status);
return;
}
}
-void
-xics_disable_irq(
- u_int virq
- )
-{
- u_int irq;
- unsigned long status;
- long call_status;
+void xics_disable_irq(u_int virq)
+{
+ u_int irq;
+ long call_status;
virq -= XICS_IRQ_OFFSET;
irq = virt_irq_to_real(virq);
- call_status = rtas_call(ibm_int_off, 1, 1, (unsigned long*)&status,
- irq);
- if( call_status != 0 ) {
- printk("xics_disable_irq: irq=%x: rtas_call failed, retn=%lx\n",
+ if (irq == XICS_IPI)
+ return;
+
+ call_status = rtas_call(ibm_int_off, 1, 1, NULL, irq);
+ if (call_status != 0) {
+ printk("xics_disable_irq: irq=%x: ibm_int_off returned %lx\n",
irq, call_status);
return;
}
}
-void
-xics_end_irq(
- u_int irq
- )
+void xics_end_irq(u_int irq)
{
int cpu = smp_processor_id();
- ops->cppr_info(cpu, 0); /* actually the value overwritten by ack */
- iosync();
- ops->xirr_info_set(cpu, ((0xff<<24) | (virt_irq_to_real(irq-XICS_IRQ_OFFSET))));
iosync();
+ ops->xirr_info_set(cpu, ((0xff<<24) |
+ (virt_irq_to_real(irq-XICS_IRQ_OFFSET))));
}
-void
-xics_mask_and_ack_irq(u_int irq)
+void xics_mask_and_ack_irq(u_int irq)
{
int cpu = smp_processor_id();
- if( irq < XICS_IRQ_OFFSET ) {
+ if (irq < XICS_IRQ_OFFSET) {
i8259_pic.ack(irq);
iosync();
- ops->xirr_info_set(cpu, ((0xff<<24) | xics_irq_8259_cascade_real));
- iosync();
- }
- else {
- ops->cppr_info(cpu, 0xff);
+ ops->xirr_info_set(cpu, ((0xff<<24) |
+ xics_irq_8259_cascade_real));
iosync();
}
}
-int
-xics_get_irq(struct pt_regs *regs)
+int xics_get_irq(struct pt_regs *regs)
{
- u_int cpu = smp_processor_id();
- u_int vec;
+ u_int cpu = smp_processor_id();
+ u_int vec;
int irq;
vec = ops->xirr_info_get(cpu);
/* (vec >> 24) == old priority */
vec &= 0x00ffffff;
+
/* for sanity, this had better be < NR_IRQS - 16 */
- if( vec == xics_irq_8259_cascade_real ) {
+ if (vec == xics_irq_8259_cascade_real) {
irq = i8259_irq(cpu);
- if(irq == -1) {
+ if (irq == -1) {
/* Spurious cascaded interrupt. Still must ack xics */
xics_end_irq(XICS_IRQ_OFFSET + xics_irq_8259_cascade);
irq = -1;
}
- } else if( vec == XICS_IRQ_SPURIOUS ) {
+ } else if (vec == XICS_IRQ_SPURIOUS) {
irq = -1;
} else {
irq = real_irq_to_virt(vec) + XICS_IRQ_OFFSET;
@@ -250,45 +316,47 @@
return irq;
}
-struct xics_ipi_struct {
- volatile unsigned long value;
-} ____cacheline_aligned;
+#ifdef CONFIG_SMP
extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
-#ifdef CONFIG_SMP
-void xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
{
int cpu = smp_processor_id();
ops->qirr_info(cpu, 0xff);
while (xics_ipi_message[cpu].value) {
- if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, &xics_ipi_message[cpu].value)) {
+ if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION,
+ &xics_ipi_message[cpu].value)) {
mb();
smp_message_recv(PPC_MSG_CALL_FUNCTION, regs);
}
- if (test_and_clear_bit(PPC_MSG_RESCHEDULE, &xics_ipi_message[cpu].value)) {
+ if (test_and_clear_bit(PPC_MSG_RESCHEDULE,
+ &xics_ipi_message[cpu].value)) {
mb();
smp_message_recv(PPC_MSG_RESCHEDULE, regs);
}
#if 0
- if (test_and_clear_bit(PPC_MSG_MIGRATE_TASK, &xics_ipi_message[cpu].value)) {
+ if (test_and_clear_bit(PPC_MSG_MIGRATE_TASK,
+ &xics_ipi_message[cpu].value)) {
mb();
smp_message_recv(PPC_MSG_MIGRATE_TASK, regs);
}
#endif
#ifdef CONFIG_XMON
- if (test_and_clear_bit(PPC_MSG_XMON_BREAK, &xics_ipi_message[cpu].value)) {
+ if (test_and_clear_bit(PPC_MSG_XMON_BREAK,
+ &xics_ipi_message[cpu].value)) {
mb();
smp_message_recv(PPC_MSG_XMON_BREAK, regs);
}
#endif
}
+ return IRQ_HANDLED;
}
void xics_cause_IPI(int cpu)
{
- ops->qirr_info(cpu,0) ;
+ ops->qirr_info(cpu, IPI_PRIORITY);
}
void xics_setup_cpu(void)
@@ -298,15 +366,20 @@
ops->cppr_info(cpu, 0xff);
iosync();
}
+
#endif /* CONFIG_SMP */
-void
-xics_init_IRQ( void )
+void xics_init_IRQ(void)
{
int i;
unsigned long intr_size = 0;
struct device_node *np;
uint *ireg, ilen, indx=0;
+ unsigned long intr_base = 0;
+ struct xics_interrupt_node {
+ unsigned long long addr;
+ unsigned long long size;
+ } inodes[NR_CPUS*2];
ppc64_boot_msg(0x20, "XICS Init");
@@ -386,23 +459,24 @@
xics_irq_8259_cascade = virt_irq_create_mapping(xics_irq_8259_cascade_real);
}
- if (naca->platform == PLATFORM_PSERIES) {
+ if (systemcfg->platform == PLATFORM_PSERIES) {
#ifdef CONFIG_SMP
for (i = 0; i < NR_CPUS; ++i) {
if (!cpu_possible(i))
continue;
- xics_info.per_cpu[i] =
- __ioremap((ulong)inodes[i].addr,
- (ulong)inodes[i].size, _PAGE_NO_CACHE);
+ xics_per_cpu[i] = __ioremap((ulong)inodes[i].addr,
+ (ulong)inodes[i].size,
+ _PAGE_NO_CACHE);
}
#else
- xics_info.per_cpu[0] = __ioremap((ulong)intr_base, intr_size, _PAGE_NO_CACHE);
+ xics_per_cpu[0] = __ioremap((ulong)intr_base, intr_size,
+ _PAGE_NO_CACHE);
#endif /* CONFIG_SMP */
#ifdef CONFIG_PPC_PSERIES
/* actually iSeries does not use any of xics...but it has link dependencies
* for now, except this new one...
*/
- } else if (naca->platform == PLATFORM_PSERIES_LPAR) {
+ } else if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
ops = &pSeriesLP_ops;
#endif
}
@@ -417,8 +491,8 @@
ops->cppr_info(boot_cpuid, 0xff);
iosync();
if (xics_irq_8259_cascade != -1) {
- if (request_irq(xics_irq_8259_cascade + XICS_IRQ_OFFSET, no_action,
- 0, "8259 cascade", 0))
+ if (request_irq(xics_irq_8259_cascade + XICS_IRQ_OFFSET,
+ no_action, 0, "8259 cascade", 0))
printk(KERN_ERR "xics_init_IRQ: couldn't get 8259 cascade\n");
i8259_init();
}
diff -Nru a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
--- a/arch/ppc64/mm/init.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/mm/init.c Thu Jun 19 00:45:34 2003
@@ -36,6 +36,7 @@
#include <linux/delay.h>
#include <linux/bootmem.h>
#include <linux/highmem.h>
+#include <linux/proc_fs.h>
#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/blk.h> /* for initrd_* */
#endif
@@ -58,6 +59,7 @@
#include <asm/eeh.h>
#include <asm/processor.h>
#include <asm/mmzone.h>
+#include <asm/cputable.h>
#include <asm/ppcdebug.h>
@@ -95,7 +97,7 @@
/* This is declared as we are using the more or less generic
* include/asm-ppc64/tlb.h file -- tgall
*/
-struct mmu_gather mmu_gathers[NR_CPUS];
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
void show_mem(void)
{
@@ -510,6 +512,37 @@
}
#endif
+static struct kcore_list kcore_vmem;
+
+static int __init setup_kcore(void)
+{
+ int i;
+
+ for (i=0; i < lmb.memory.cnt; i++) {
+ unsigned long physbase, size;
+ unsigned long type = lmb.memory.region[i].type;
+ struct kcore_list *kcore_mem;
+
+ if (type != LMB_MEMORY_AREA)
+ continue;
+
+ physbase = lmb.memory.region[i].physbase;
+ size = lmb.memory.region[i].size;
+
+ /* GFP_ATOMIC to avoid might_sleep warnings during boot */
+ kcore_mem = kmalloc(sizeof(struct kcore_list), GFP_ATOMIC);
+ if (!kcore_mem)
+ panic("mem_init: kmalloc failed\n");
+
+ kclist_add(kcore_mem, __va(physbase), size);
+ }
+
+ kclist_add(&kcore_vmem, (void *)VMALLOC_START, VMALLOC_END-VMALLOC_START);
+
+ return 0;
+}
+module_init(setup_kcore);
+
void initialize_paca_hardware_interrupt_stack(void);
void __init mem_init(void)
@@ -668,7 +701,7 @@
int local = 0;
/* handle i-cache coherency */
- if (!cpu_has_noexecute()) {
+ if (!(cur_cpu_spec->cpu_features & CPU_FTR_NOEXECUTE)) {
unsigned long pfn = pte_pfn(pte);
if (pfn_valid(pfn)) {
struct page *page = pfn_to_page(pfn);
diff -Nru a/arch/ppc64/mm/numa.c b/arch/ppc64/mm/numa.c
--- a/arch/ppc64/mm/numa.c Thu Jun 19 00:45:34 2003
+++ b/arch/ppc64/mm/numa.c Thu Jun 19 00:45:34 2003
@@ -24,11 +24,22 @@
int numa_cpu_lookup_table[NR_CPUS] = { [ 0 ... (NR_CPUS - 1)] = -1};
int numa_memory_lookup_table[MAX_MEMORY >> MEMORY_INCREMENT_SHIFT] =
{ [ 0 ... ((MAX_MEMORY >> MEMORY_INCREMENT_SHIFT) - 1)] = -1};
-int numa_node_exists[MAX_NUMNODES];
+unsigned long numa_cpumask_lookup_table[MAX_NUMNODES];
+int nr_cpus_in_node[MAX_NUMNODES] = { [0 ... (MAX_NUMNODES -1)] = 0};
struct pglist_data node_data[MAX_NUMNODES];
bootmem_data_t plat_node_bdata[MAX_NUMNODES];
+static inline void map_cpu_to_node(int cpu, int node)
+{
+ dbg("cpu %d maps to domain %d\n", cpu, node);
+ numa_cpu_lookup_table[cpu] = node;
+ if (!(numa_cpumask_lookup_table[node] & 1UL << cpu)) {
+ numa_cpumask_lookup_table[node] |= 1UL << cpu;
+ nr_cpus_in_node[node]++;
+ }
+}
+
static int __init parse_numa_properties(void)
{
struct device_node *cpu;
@@ -88,9 +99,7 @@
if (max_domain < numa_domain)
max_domain = numa_domain;
- numa_cpu_lookup_table[cpu_nr] = numa_domain;
-
- dbg("cpu %d maps to domain %d\n", cpu_nr, numa_domain);
+ map_cpu_to_node(cpu_nr, numa_domain);
}
for (memory = find_type_devices("memory"); memory;
@@ -135,7 +144,7 @@
/* FIXME */
if (numa_domain == 0xffff) {
- dbg("cpu has no numa doman\n");
+ dbg("memory has no numa doman\n");
numa_domain = 0;
}
@@ -145,7 +154,28 @@
if (max_domain < numa_domain)
max_domain = numa_domain;
- numa_node_exists[numa_domain] = 1;
+ /*
+ * For backwards compatibility, OF splits the first node
+ * into two regions (the first being 0-4GB). Check for
+ * this simple case and complain if there is a gap in
+ * memory
+ */
+ if (node_data[numa_domain].node_size) {
+ unsigned long shouldstart =
+ node_data[numa_domain].node_start_pfn +
+ node_data[numa_domain].node_size;
+ if (shouldstart != (start / PAGE_SIZE)) {
+ printk(KERN_ERR "Hole in node, disabling "
+ "region start %lx length %lx\n",
+ start, size);
+ continue;
+ }
+ node_data[numa_domain].node_size += size / PAGE_SIZE;
+ } else {
+ node_data[numa_domain].node_start_pfn =
+ start / PAGE_SIZE;
+ node_data[numa_domain].node_size = size / PAGE_SIZE;
+ }
for (i = start ; i < (start+size); i += MEMORY_INCREMENT)
numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] =
@@ -164,6 +194,20 @@
return 0;
}
+void setup_nonnuma(void)
+{
+ unsigned long i;
+
+ for (i = 0; i < NR_CPUS; i++)
+ map_cpu_to_node(i, 0);
+
+ node_data[0].node_start_pfn = 0;
+ node_data[0].node_size = lmb_end_of_DRAM() / PAGE_SIZE;
+
+ for (i = 0 ; i < lmb_end_of_DRAM(); i += MEMORY_INCREMENT)
+ numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] = 0;
+}
+
void __init do_init_bootmem(void)
{
int nid;
@@ -171,32 +215,21 @@
min_low_pfn = 0;
max_low_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT;
- /* XXX FIXME: support machines without associativity information */
if (parse_numa_properties())
- BUG();
+ setup_nonnuma();
for (nid = 0; nid < numnodes; nid++) {
- unsigned long start, end;
unsigned long start_paddr, end_paddr;
int i;
unsigned long bootmem_paddr;
unsigned long bootmap_pages;
- if (!numa_node_exists[nid])
+ if (node_data[nid].node_size == 0)
continue;
- /* Find start and end of this zone */
- start = 0;
- while (numa_memory_lookup_table[start] != nid)
- start++;
-
- end = (MAX_MEMORY >> MEMORY_INCREMENT_SHIFT) - 1;
- while (numa_memory_lookup_table[end] != nid)
- end--;
- end++;
-
- start_paddr = start << MEMORY_INCREMENT_SHIFT;
- end_paddr = end << MEMORY_INCREMENT_SHIFT;
+ start_paddr = node_data[nid].node_start_pfn * PAGE_SIZE;
+ end_paddr = start_paddr +
+ (node_data[nid].node_size * PAGE_SIZE);
dbg("node %d\n", nid);
dbg("start_paddr = %lx\n", start_paddr);
@@ -204,7 +237,7 @@
NODE_DATA(nid)->bdata = &plat_node_bdata[nid];
- bootmap_pages = bootmem_bootmap_pages(end_paddr - start_paddr);
+ bootmap_pages = bootmem_bootmap_pages((end_paddr - start_paddr) >> PAGE_SHIFT);
dbg("bootmap_pages = %lx\n", bootmap_pages);
bootmem_paddr = lmb_alloc_base(bootmap_pages << PAGE_SHIFT,
@@ -278,7 +311,7 @@
unsigned long start_pfn;
unsigned long end_pfn;
- if (!numa_node_exists[nid])
+ if (node_data[nid].node_size == 0)
continue;
start_pfn = plat_node_bdata[nid].node_boot_start >> PAGE_SHIFT;
diff -Nru a/arch/sparc64/kernel/module.c b/arch/sparc64/kernel/module.c
--- a/arch/sparc64/kernel/module.c Thu Jun 19 00:45:34 2003
+++ b/arch/sparc64/kernel/module.c Thu Jun 19 00:45:34 2003
@@ -138,7 +138,9 @@
/* Free memory returned from module_core_alloc/module_init_alloc */
void module_free(struct module *mod, void *module_region)
{
+ write_lock(&vmlist_lock);
module_unmap(module_region);
+ write_unlock(&vmlist_lock);
/* FIXME: If module_region == mod->init_region, trim exception
table entries. */
}
diff -Nru a/arch/x86_64/kernel/module.c b/arch/x86_64/kernel/module.c
--- a/arch/x86_64/kernel/module.c Thu Jun 19 00:45:34 2003
+++ b/arch/x86_64/kernel/module.c Thu Jun 19 00:45:34 2003
@@ -48,7 +48,6 @@
for (prevp = &mod_vmlist ; (map = *prevp) ; prevp = &map->next) {
if ((unsigned long)map->addr == addr) {
*prevp = map->next;
- write_unlock(&vmlist_lock);
goto found;
}
}
@@ -57,6 +56,7 @@
return;
found:
unmap_vm_area(map);
+ write_unlock(&vmlist_lock);
if (map->pages) {
for (i = 0; i < map->nr_pages; i++)
if (map->pages[i])
diff -Nru a/drivers/acpi/osl.c b/drivers/acpi/osl.c
--- a/drivers/acpi/osl.c Thu Jun 19 00:45:34 2003
+++ b/drivers/acpi/osl.c Thu Jun 19 00:45:34 2003
@@ -252,7 +252,14 @@
irq = acpi_fadt.sci_int;
#ifdef CONFIG_IA64
- irq = gsi_to_vector(irq);
+ int vector;
+
+ vector = acpi_irq_to_vector(irq);
+ if (vector < 0) {
+ printk(KERN_ERR PREFIX "SCI (IRQ%d) not registerd\n", irq);
+ return AE_OK;
+ }
+ irq = vector;
#endif
acpi_irq_irq = irq;
acpi_irq_handler = handler;
@@ -270,7 +277,7 @@
{
if (acpi_irq_handler) {
#ifdef CONFIG_IA64
- irq = gsi_to_vector(irq);
+ irq = acpi_irq_to_vector(irq);
#endif
free_irq(irq, acpi_irq);
acpi_irq_handler = NULL;
@@ -455,6 +462,9 @@
int result = 0;
int size = 0;
struct pci_bus bus;
+#ifdef CONFIG_IA64
+ struct pci_controller ctrl;
+#endif
if (!value)
return AE_BAD_PARAMETER;
@@ -474,6 +484,10 @@
}
bus.number = pci_id->bus;
+#ifdef CONFIG_IA64
+ ctrl.segment = pci_id->segment;
+ bus.sysdata = &ctrl;
+#endif
result = pci_root_ops->read(&bus, PCI_DEVFN(pci_id->device,
pci_id->function),
reg, size, value);
@@ -491,6 +505,9 @@
int result = 0;
int size = 0;
struct pci_bus bus;
+#ifdef CONFIG_IA64
+ struct pci_controller ctrl;
+#endif
switch (width) {
case 8:
@@ -507,6 +524,10 @@
}
bus.number = pci_id->bus;
+#ifdef CONFIG_IA64
+ ctrl.segment = pci_id->segment;
+ bus.sysdata = &ctrl;
+#endif
result = pci_root_ops->write(&bus, PCI_DEVFN(pci_id->device,
pci_id->function),
reg, size, value);
diff -Nru a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
--- a/drivers/acpi/pci_irq.c Thu Jun 19 00:45:34 2003
+++ b/drivers/acpi/pci_irq.c Thu Jun 19 00:45:34 2003
@@ -24,6 +24,8 @@
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
+#include <linux/config.h>
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -36,9 +38,16 @@
#ifdef CONFIG_X86_IO_APIC
#include <asm/mpspec.h>
#endif
+#ifdef CONFIG_IOSAPIC
+# include <asm/iosapic.h>
+#endif
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
+#ifdef CONFIG_X86
+# define PCI_SEGMENT(x) 0 /* XXX fix me */
+#endif
+
#define _COMPONENT ACPI_PCI_COMPONENT
ACPI_MODULE_NAME ("pci_irq")
@@ -248,6 +257,8 @@
return_VALUE(0);
}
+ entry->irq = entry->link.index;
+
if (!entry->irq && entry->link.handle) {
entry->irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index);
if (!entry->irq) {
@@ -356,7 +367,11 @@
}
}
+#ifdef CONFIG_IA64
+ dev->irq = gsi_to_irq(irq);
+#else
dev->irq = irq;
+#endif
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %s using IRQ %d\n", dev->slot_name, dev->irq));
@@ -369,6 +384,10 @@
irq_mask |= (1 << dev->irq);
eisa_set_level_irq(dev->irq);
}
+#endif
+#ifdef CONFIG_IOSAPIC
+ if (acpi_irq_model == ACPI_IRQ_MODEL_IOSAPIC)
+ iosapic_enable_intr(dev->irq);
#endif
return_VALUE(dev->irq);
diff -Nru a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
--- a/drivers/acpi/pci_root.c Thu Jun 19 00:45:34 2003
+++ b/drivers/acpi/pci_root.c Thu Jun 19 00:45:34 2003
@@ -23,6 +23,8 @@
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
+#include <linux/config.h>
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -248,8 +250,6 @@
switch (status) {
case AE_OK:
root->id.segment = (u16) value;
- printk("_SEG exists! Unsupported. Abort.\n");
- BUG();
break;
case AE_NOT_FOUND:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -311,7 +311,12 @@
* PCI namespace does not get created until this call is made (and
* thus the root bridge's pci_dev does not exist).
*/
+#ifdef CONFIG_X86
root->bus = pcibios_scan_root(root->id.bus);
+#else
+ root->bus = pcibios_scan_root(root->handle,
+ root->id.segment, root->id.bus);
+#endif
if (!root->bus) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Bus %02x:%02x not present in PCI namespace\n",
diff -Nru a/drivers/char/drm/drm_memory.h b/drivers/char/drm/drm_memory.h
--- a/drivers/char/drm/drm_memory.h Thu Jun 19 00:45:34 2003
+++ b/drivers/char/drm/drm_memory.h Thu Jun 19 00:45:34 2003
@@ -32,6 +32,10 @@
#include <linux/config.h>
#include <linux/highmem.h>
#include "drmP.h"
+#include <linux/vmalloc.h>
+
+#include <asm/agp.h>
+#include <asm/tlbflush.h>
/* Cut down version of drm_memory_debug.h, which used to be called
* drm_memory.h. If you want the debug functionality, change 0 to 1
diff -Nru a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
--- a/drivers/scsi/qla1280.c Thu Jun 19 00:45:35 2003
+++ b/drivers/scsi/qla1280.c Thu Jun 19 00:45:35 2003
@@ -284,7 +284,7 @@
#define QL1280_TARGET_MODE_SUPPORT 0 /* Target mode support */
#define QL1280_LUN_SUPPORT 0
#define WATCHDOGTIMER 0
-#define MEMORY_MAPPED_IO 0
+#define MEMORY_MAPPED_IO 1
#define DEBUG_QLA1280_INTR 0
#define USE_NVRAM_DEFAULTS 0
#define DEBUG_PRINT_NVRAM 0
@@ -2491,7 +2491,7 @@
/*
* Get memory mapped I/O address.
*/
- pci_read_config_word (ha->pdev, PCI_BASE_ADDRESS_1, &mmapbase);
+ pci_read_config_dword (ha->pdev, PCI_BASE_ADDRESS_1, &mmapbase);
mmapbase &= PCI_BASE_ADDRESS_MEM_MASK;
/*
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c Thu Jun 19 00:45:35 2003
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c Thu Jun 19 00:45:35 2003
@@ -295,11 +295,7 @@
#ifndef SYM_LINUX_DYNAMIC_DMA_MAPPING
typedef u_long bus_addr_t;
#else
-#if SYM_CONF_DMA_ADDRESSING_MODE > 0
-typedef dma64_addr_t bus_addr_t;
-#else
typedef dma_addr_t bus_addr_t;
-#endif
#endif
/*
diff -Nru a/drivers/serial/8250_hcdp.c b/drivers/serial/8250_hcdp.c
--- a/drivers/serial/8250_hcdp.c Thu Jun 19 00:45:34 2003
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,221 +0,0 @@
-/*
- * linux/drivers/char/hcdp_serial.c
- *
- * Copyright (C) 2002 Hewlett-Packard Co.
- * Khalid Aziz <khalid_aziz@hp.com>
- *
- * Parse the EFI HCDP table to locate serial console and debug ports and initialize them.
- *
- * 2002/08/29 davidm Adjust it to new 2.5 serial driver infrastructure (untested).
- */
-#include <linux/config.h>
-
-#include <linux/kernel.h>
-#include <linux/efi.h>
-#include <linux/init.h>
-#include <linux/tty.h>
-#include <linux/serial.h>
-#include <linux/serial_core.h>
-#include <linux/types.h>
-#include <linux/acpi.h>
-
-#include <asm/io.h>
-#include <asm/serial.h>
-#include <asm/acpi.h>
-
-#include "8250_hcdp.h"
-
-#undef SERIAL_DEBUG_HCDP
-
-/*
- * Parse the HCDP table to find descriptions for headless console and debug serial ports
- * and add them to rs_table[]. A pointer to HCDP table is passed as parameter. This
- * function should be called before serial_console_init() is called to make sure the HCDP
- * serial console will be available for use. IA-64 kernel calls this function from
- * setup_arch() after the EFI and ACPI tables have been parsed.
- */
-void __init
-setup_serial_hcdp (void *tablep)
-{
- hcdp_dev_t *hcdp_dev;
- struct uart_port port;
- unsigned long iobase;
- hcdp_t hcdp;
- int gsi, nr;
-#if 0
- static int shift_once = 1;
-#endif
-
-#ifdef SERIAL_DEBUG_HCDP
- printk("Entering setup_serial_hcdp()\n");
-#endif
-
- /* Verify we have a valid table pointer */
- if (!tablep)
- return;
-
- memset(&port, 0, sizeof(port));
-
- /*
- * Don't trust firmware to give us a table starting at an aligned address. Make a
- * local copy of the HCDP table with aligned structures.
- */
- memcpy(&hcdp, tablep, sizeof(hcdp));
-
- /*
- * Perform a sanity check on the table. Table should have a signature of "HCDP"
- * and it should be atleast 82 bytes long to have any useful information.
- */
- if ((strncmp(hcdp.signature, HCDP_SIGNATURE, HCDP_SIG_LEN) != 0))
- return;
- if (hcdp.len < 82)
- return;
-
-#ifdef SERIAL_DEBUG_HCDP
- printk("setup_serial_hcdp(): table pointer = 0x%p, sig = '%.4s'\n",
- tablep, hcdp.signature);
- printk(" length = %d, rev = %d, ", hcdp.len, hcdp.rev);
- printk("OEM ID = %.6s, # of entries = %d\n", hcdp.oemid, hcdp.num_entries);
-#endif
-
- /*
- * Parse each device entry
- */
- for (nr = 0; nr < hcdp.num_entries; nr++) {
- hcdp_dev = hcdp.hcdp_dev + nr;
- /*
- * We will parse only the primary console device which is the first entry
- * for these devices. We will ignore rest of the entries for the same type
- * device that has already been parsed and initialized
- */
- if (hcdp_dev->type != HCDP_DEV_CONSOLE)
- continue;
-
- iobase = ((u64) hcdp_dev->base_addr.addrhi << 32) | hcdp_dev->base_addr.addrlo;
- gsi = hcdp_dev->global_int;
-
- /* See PCI spec v2.2, Appendix D (Class Codes): */
- switch (hcdp_dev->pci_prog_intfc) {
- case 0x00: port.type = PORT_8250; break;
- case 0x01: port.type = PORT_16450; break;
- case 0x02: port.type = PORT_16550; break;
- case 0x03: port.type = PORT_16650; break;
- case 0x04: port.type = PORT_16750; break;
- case 0x05: port.type = PORT_16850; break;
- case 0x06: port.type = PORT_16C950; break;
- default:
- printk(KERN_WARNING"warning: EFI HCDP table reports unknown serial "
- "programming interface 0x%02x; will autoprobe.\n",
- hcdp_dev->pci_prog_intfc);
- port.type = PORT_UNKNOWN;
- break;
- }
-
-#ifdef SERIAL_DEBUG_HCDP
- printk(" type = %s, uart = %d\n", ((hcdp_dev->type == HCDP_DEV_CONSOLE)
- ? "Headless Console" : ((hcdp_dev->type == HCDP_DEV_DEBUG)
- ? "Debug port" : "Huh????")),
- port.type);
- printk(" base address space = %s, base address = 0x%lx\n",
- ((hcdp_dev->base_addr.space_id == ACPI_MEM_SPACE)
- ? "Memory Space" : ((hcdp_dev->base_addr.space_id == ACPI_IO_SPACE)
- ? "I/O space" : "PCI space")),
- iobase);
- printk(" gsi = %d, baud rate = %lu, bits = %d, clock = %d\n",
- gsi, (unsigned long) hcdp_dev->baud, hcdp_dev->bits, hcdp_dev->clock_rate);
- if (hcdp_dev->base_addr.space_id == ACPI_PCICONF_SPACE)
- printk(" PCI id: %02x:%02x:%02x, vendor ID=0x%x, dev ID=0x%x\n",
- hcdp_dev->pci_seg, hcdp_dev->pci_bus, hcdp_dev->pci_dev,
- hcdp_dev->pci_vendor_id, hcdp_dev->pci_dev_id);
-#endif
- /*
- * Now fill in a port structure to update the 8250 port table..
- */
- if (hcdp_dev->clock_rate)
- port.uartclk = hcdp_dev->clock_rate;
- else
- port.uartclk = BASE_BAUD * 16;
-
- /*
- * Check if this is an I/O mapped address or a memory mapped address
- */
- if (hcdp_dev->base_addr.space_id == ACPI_MEM_SPACE) {
- port.iobase = 0;
- port.mapbase = iobase;
- port.membase = ioremap(iobase, 64);
- port.iotype = SERIAL_IO_MEM;
- } else if (hcdp_dev->base_addr.space_id == ACPI_IO_SPACE) {
- port.iobase = iobase;
- port.mapbase = 0;
- port.membase = NULL;
- port.iotype = SERIAL_IO_PORT;
- } else if (hcdp_dev->base_addr.space_id == ACPI_PCICONF_SPACE) {
- printk(KERN_WARNING"warning: No support for PCI serial console\n");
- return;
- }
-#ifdef CONFIG_IA64
- port.irq = acpi_register_irq(gsi, ACPI_ACTIVE_HIGH, ACPI_EDGE_SENSITIVE);
-#else
- port.irq = gsi;
-#endif
- port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
- if (gsi)
- port.flags |= ASYNC_AUTO_IRQ;
-
- /*
- * Note: the above memset() initializes port.line to 0, so we register
- * this port as ttyS0.
- */
- if (early_serial_setup(&port) < 0) {
- printk("setup_serial_hcdp(): early_serial_setup() for HCDP serial "
- "console port failed. Will try any additional consoles in HCDP.\n");
- continue;
- }
- break;
- }
-
-#ifdef SERIAL_DEBUG_HCDP
- printk("Leaving setup_serial_hcdp()\n");
-#endif
-}
-
-#ifdef CONFIG_IA64_EARLY_PRINTK_UART
-unsigned long
-hcdp_early_uart (void)
-{
- efi_system_table_t *systab;
- efi_config_table_t *config_tables;
- unsigned long addr = 0;
- hcdp_t *hcdp = 0;
- hcdp_dev_t *dev;
- int i;
-
- systab = (efi_system_table_t *) ia64_boot_param->efi_systab;
- if (!systab)
- return 0;
- systab = __va(systab);
-
- config_tables = (efi_config_table_t *) systab->tables;
- if (!config_tables)
- return 0;
- config_tables = __va(config_tables);
-
- for (i = 0; i < systab->nr_tables; i++) {
- if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) {
- hcdp = (hcdp_t *) config_tables[i].table;
- break;
- }
- }
- if (!hcdp)
- return 0;
- hcdp = __va(hcdp);
-
- for (i = 0, dev = hcdp->hcdp_dev; i < hcdp->num_entries; i++, dev++) {
- if (dev->type == HCDP_DEV_CONSOLE) {
- addr = (u64) dev->base_addr.addrhi << 32 | dev->base_addr.addrlo;
- break;
- }
- }
- return addr;
-}
-#endif /* CONFIG_IA64_EARLY_PRINTK_UART */
diff -Nru a/drivers/serial/8250_hcdp.h b/drivers/serial/8250_hcdp.h
--- a/drivers/serial/8250_hcdp.h Thu Jun 19 00:45:34 2003
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,79 +0,0 @@
-/*
- * drivers/serial/8250_hcdp.h
- *
- * Copyright (C) 2002 Hewlett-Packard Co.
- * Khalid Aziz <khalid_aziz@hp.com>
- *
- * Definitions for HCDP defined serial ports (Serial console and debug
- * ports)
- */
-
-/* ACPI table signatures */
-#define HCDP_SIG_LEN 4
-#define HCDP_SIGNATURE "HCDP"
-
-/* Space ID as defined in ACPI generic address structure */
-#define ACPI_MEM_SPACE 0
-#define ACPI_IO_SPACE 1
-#define ACPI_PCICONF_SPACE 2
-
-/*
- * Maximum number of HCDP devices we want to read in
- */
-#define MAX_HCDP_DEVICES 6
-
-/*
- * Default UART clock rate if clock rate is 0 in HCDP table.
- */
-#define DEFAULT_UARTCLK 115200
-
-/*
- * ACPI Generic Address Structure
- */
-typedef struct {
- u8 space_id;
- u8 bit_width;
- u8 bit_offset;
- u8 resv;
- u32 addrlo;
- u32 addrhi;
-} acpi_gen_addr;
-
-/* HCDP Device descriptor entry types */
-#define HCDP_DEV_CONSOLE 0
-#define HCDP_DEV_DEBUG 1
-
-/* HCDP Device descriptor type */
-typedef struct {
- u8 type;
- u8 bits;
- u8 parity;
- u8 stop_bits;
- u8 pci_seg;
- u8 pci_bus;
- u8 pci_dev;
- u8 pci_func;
- u64 baud;
- acpi_gen_addr base_addr;
- u16 pci_dev_id;
- u16 pci_vendor_id;
- u32 global_int;
- u32 clock_rate;
- u8 pci_prog_intfc;
- u8 resv;
-} hcdp_dev_t;
-
-/* HCDP Table format */
-typedef struct {
- u8 signature[4];
- u32 len;
- u8 rev;
- u8 chksum;
- u8 oemid[6];
- u8 oem_tabid[8];
- u32 oem_rev;
- u8 creator_id[4];
- u32 creator_rev;
- u32 num_entries;
- hcdp_dev_t hcdp_dev[MAX_HCDP_DEVICES];
-} hcdp_t;
diff -Nru a/drivers/serial/Kconfig b/drivers/serial/Kconfig
--- a/drivers/serial/Kconfig Thu Jun 19 00:45:34 2003
+++ b/drivers/serial/Kconfig Thu Jun 19 00:45:34 2003
@@ -77,7 +77,7 @@
a module, say M here and read <file:Documentation/modules.txt>.
If unsure, say N.
-config SERIAL_HCDP
+config SERIAL_8250_HCDP
bool "8250/16550 device discovery support via EFI HCDP table"
depends on IA64
---help---
diff -Nru a/drivers/serial/Makefile b/drivers/serial/Makefile
--- a/drivers/serial/Makefile Thu Jun 19 00:45:34 2003
+++ b/drivers/serial/Makefile Thu Jun 19 00:45:34 2003
@@ -9,6 +9,7 @@
serial-8250-$(CONFIG_PCI) += 8250_pci.o
serial-8250-$(CONFIG_PNP) += 8250_pnp.o
serial-8250-$(CONFIG_SERIAL_HCDP) += 8250_hcdp.o
+serial-8250-$(CONFIG_ACPI) += acpi.o
obj-$(CONFIG_SERIAL_CORE) += core.o
obj-$(CONFIG_SERIAL_21285) += 21285.o
diff -Nru a/fs/fcntl.c b/fs/fcntl.c
--- a/fs/fcntl.c Thu Jun 19 00:45:34 2003
+++ b/fs/fcntl.c Thu Jun 19 00:45:34 2003
@@ -12,6 +12,7 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/security.h>
+#include <linux/ptrace.h>
#include <asm/poll.h>
#include <asm/siginfo.h>
@@ -80,11 +81,11 @@
*/
static int locate_fd(struct files_struct *files,
- struct file *file, int orig_start)
+ struct file *file, unsigned int orig_start)
{
unsigned int newfd;
+ unsigned int start;
int error;
- int start;
error = -EINVAL;
if (orig_start >= current->rlim[RLIMIT_NOFILE].rlim_cur)
@@ -129,7 +130,7 @@
return error;
}
-static int dupfd(struct file *file, int start)
+static int dupfd(struct file *file, unsigned int start)
{
struct files_struct * files = current->files;
int fd;
@@ -286,10 +287,8 @@
switch (cmd) {
case F_DUPFD:
- if (arg < NR_OPEN) {
- get_file(filp);
- err = dupfd(filp, arg);
- }
+ get_file(filp);
+ err = dupfd(filp, arg);
break;
case F_GETFD:
err = get_close_on_exec(fd);
@@ -305,11 +304,11 @@
err = setfl(fd, filp, arg);
break;
case F_GETLK:
- err = fcntl_getlk(filp, (struct flock *) arg);
+ err = fcntl_getlk(filp, (struct flock __user *) arg);
break;
case F_SETLK:
case F_SETLKW:
- err = fcntl_setlk(filp, cmd, (struct flock *) arg);
+ err = fcntl_setlk(filp, cmd, (struct flock __user *) arg);
break;
case F_GETOWN:
/*
@@ -394,11 +393,11 @@
switch (cmd) {
case F_GETLK64:
- err = fcntl_getlk64(filp, (struct flock64 *) arg);
+ err = fcntl_getlk64(filp, (struct flock64 __user *) arg);
break;
case F_SETLK64:
case F_SETLKW64:
- err = fcntl_setlk64(filp, cmd, (struct flock64 *) arg);
+ err = fcntl_setlk64(filp, cmd, (struct flock64 __user *) arg);
break;
default:
err = do_fcntl(fd, cmd, arg, filp);
diff -Nru a/fs/proc/base.c b/fs/proc/base.c
--- a/fs/proc/base.c Thu Jun 19 00:45:34 2003
+++ b/fs/proc/base.c Thu Jun 19 00:45:34 2003
@@ -58,6 +58,13 @@
PROC_PID_MAPS,
PROC_PID_MOUNTS,
PROC_PID_WCHAN,
+#ifdef CONFIG_SECURITY
+ PROC_PID_ATTR,
+ PROC_PID_ATTR_CURRENT,
+ PROC_PID_ATTR_PREV,
+ PROC_PID_ATTR_EXEC,
+ PROC_PID_ATTR_FSCREATE,
+#endif
PROC_PID_FD_DIR = 0x8000, /* 0x8000-0xffff */
};
@@ -82,11 +89,23 @@
E(PROC_PID_ROOT, "root", S_IFLNK|S_IRWXUGO),
E(PROC_PID_EXE, "exe", S_IFLNK|S_IRWXUGO),
E(PROC_PID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
+#ifdef CONFIG_SECURITY
+ E(PROC_PID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
+#endif
#ifdef CONFIG_KALLSYMS
E(PROC_PID_WCHAN, "wchan", S_IFREG|S_IRUGO),
#endif
{0,0,NULL,0}
};
+#ifdef CONFIG_SECURITY
+static struct pid_entry attr_stuff[] = {
+ E(PROC_PID_ATTR_CURRENT, "current", S_IFREG|S_IRUGO|S_IWUGO),
+ E(PROC_PID_ATTR_PREV, "prev", S_IFREG|S_IRUGO),
+ E(PROC_PID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO),
+ E(PROC_PID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
+ {0,0,NULL,0}
+};
+#endif
#undef E
static inline struct task_struct *proc_task(struct inode *inode)
@@ -322,21 +341,23 @@
return proc_check_root(inode);
}
-extern ssize_t proc_pid_read_maps(struct task_struct *, struct file *,
- char *, size_t, loff_t *);
-static ssize_t pid_maps_read(struct file * file, char * buf,
- size_t count, loff_t *ppos)
+extern struct seq_operations proc_pid_maps_op;
+static int maps_open(struct inode *inode, struct file *file)
{
- struct inode * inode = file->f_dentry->d_inode;
struct task_struct *task = proc_task(inode);
- ssize_t res;
-
- res = proc_pid_read_maps(task, file, buf, count, ppos);
- return res;
+ int ret = seq_open(file, &proc_pid_maps_op);
+ if (!ret) {
+ struct seq_file *m = file->private_data;
+ m->private = task;
+ }
+ return ret;
}
static struct file_operations proc_maps_operations = {
- .read = pid_maps_read,
+ .open = maps_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
};
extern struct seq_operations mounts_op;
@@ -409,8 +430,10 @@
if (count + *ppos > length)
count = length - *ppos;
end = count + *ppos;
- copy_to_user(buf, (char *) page + *ppos, count);
- *ppos = end;
+ if (copy_to_user(buf, (char *) page + *ppos, count))
+ count = -EFAULT;
+ else
+ *ppos = end;
free_page(page);
return count;
}
@@ -537,13 +560,13 @@
static loff_t mem_lseek(struct file * file, loff_t offset, int orig)
{
switch (orig) {
- case 0:
+ case 0:
file->f_pos = offset;
break;
- case 1:
+ case 1:
file->f_pos += offset;
break;
- default:
+ default:
return -EINVAL;
}
force_successful_syscall_return();
@@ -639,6 +662,12 @@
.follow_link = proc_pid_follow_link
};
+static int pid_alive(struct task_struct *p)
+{
+ BUG_ON(p->pids[PIDTYPE_PID].pidptr != &p->pids[PIDTYPE_PID].pid);
+ return atomic_read(&p->pids[PIDTYPE_PID].pid.count);
+}
+
#define NUMBUF 10
static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
@@ -650,6 +679,9 @@
char buf[NUMBUF];
struct files_struct * files;
+ retval = -ENOENT;
+ if (!pid_alive(p))
+ goto out;
retval = 0;
pid = p->pid;
@@ -704,58 +736,68 @@
return retval;
}
-static int proc_base_readdir(struct file * filp,
- void * dirent, filldir_t filldir)
+static int proc_pident_readdir(struct file *filp,
+ void *dirent, filldir_t filldir,
+ struct pid_entry *ents, unsigned int nents)
{
int i;
int pid;
- struct inode *inode = filp->f_dentry->d_inode;
+ struct dentry *dentry = filp->f_dentry;
+ struct inode *inode = dentry->d_inode;
struct pid_entry *p;
- int ret = 0;
+ ino_t ino;
+ int ret;
- lock_kernel();
+ ret = -ENOENT;
+ if (!pid_alive(proc_task(inode)))
+ goto out;
+ ret = 0;
pid = proc_task(inode)->pid;
- if (!pid) {
- ret = -ENOENT;
- goto out;
- }
i = filp->f_pos;
switch (i) {
- case 0:
- if (filldir(dirent, ".", 1, i, inode->i_ino, DT_DIR) < 0)
- goto out;
- i++;
- filp->f_pos++;
- /* fall through */
- case 1:
- if (filldir(dirent, "..", 2, i, PROC_ROOT_INO, DT_DIR) < 0)
+ case 0:
+ ino = inode->i_ino;
+ if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
+ goto out;
+ i++;
+ filp->f_pos++;
+ /* fall through */
+ case 1:
+ ino = parent_ino(dentry);
+ if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
+ goto out;
+ i++;
+ filp->f_pos++;
+ /* fall through */
+ default:
+ i -= 2;
+ if (i >= nents) {
+ ret = 1;
+ goto out;
+ }
+ p = ents + i;
+ while (p->name) {
+ if (filldir(dirent, p->name, p->len, filp->f_pos,
+ fake_ino(pid, p->type), p->mode >> 12) < 0)
goto out;
- i++;
filp->f_pos++;
- /* fall through */
- default:
- i -= 2;
- if (i>=sizeof(base_stuff)/sizeof(base_stuff[0])) {
- ret = 1;
- goto out;
- }
- p = base_stuff + i;
- while (p->name) {
- if (filldir(dirent, p->name, p->len, filp->f_pos,
- fake_ino(pid, p->type), p->mode >> 12) < 0)
- goto out;
- filp->f_pos++;
- p++;
- }
+ p++;
+ }
}
ret = 1;
out:
- unlock_kernel();
return ret;
}
+static int proc_base_readdir(struct file * filp,
+ void * dirent, filldir_t filldir)
+{
+ return proc_pident_readdir(filp,dirent,filldir,
+ base_stuff,ARRAY_SIZE(base_stuff));
+}
+
/* building an inode */
static int task_dumpable(struct task_struct *task)
@@ -789,7 +831,7 @@
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->i_ino = fake_ino(task->pid, ino);
- if (!task->pid)
+ if (!pid_alive(task))
goto out_unlock;
/*
@@ -804,6 +846,7 @@
inode->i_uid = task->euid;
inode->i_gid = task->egid;
}
+ security_task_to_inode(task, inode);
out:
return inode;
@@ -823,7 +866,7 @@
*/
static int pid_revalidate(struct dentry * dentry, int flags)
{
- if (proc_task(dentry->d_inode)->pid)
+ if (pid_alive(proc_task(dentry->d_inode)))
return 1;
d_drop(dentry);
return 0;
@@ -857,18 +900,23 @@
static void pid_base_iput(struct dentry *dentry, struct inode *inode)
{
struct task_struct *task = proc_task(inode);
- write_lock_irq(&tasklist_lock);
+ spin_lock(&task->proc_lock);
if (task->proc_dentry == dentry)
task->proc_dentry = NULL;
- write_unlock_irq(&tasklist_lock);
+ spin_unlock(&task->proc_lock);
iput(inode);
}
static int pid_delete_dentry(struct dentry * dentry)
{
- return proc_task(dentry->d_inode)->pid == 0;
+ /* Is the task we represent dead?
+ * If so, then don't put the dentry on the lru list,
+ * kill it immediately.
+ */
+ return !pid_alive(proc_task(dentry->d_inode));
}
+
static struct dentry_operations pid_fd_dentry_operations =
{
.d_revalidate = pid_fd_revalidate,
@@ -924,6 +972,8 @@
if (fd == ~0U)
goto out;
+ if (!pid_alive(task))
+ goto out;
inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_FD_DIR+fd);
if (!inode)
@@ -952,8 +1002,6 @@
ei->op.proc_get_link = proc_fd_link;
dentry->d_op = &pid_fd_dentry_operations;
d_add(dentry, inode);
- if (!proc_task(dentry->d_inode)->pid)
- d_drop(dentry);
return NULL;
out_unlock2:
@@ -978,8 +1026,86 @@
.permission = proc_permission,
};
+#ifdef CONFIG_SECURITY
+static ssize_t proc_pid_attr_read(struct file * file, char * buf,
+ size_t count, loff_t *ppos)
+{
+ struct inode * inode = file->f_dentry->d_inode;
+ unsigned long page;
+ ssize_t length;
+ ssize_t end;
+ struct task_struct *task = proc_task(inode);
+
+ if (count > PAGE_SIZE)
+ count = PAGE_SIZE;
+ if (!(page = __get_free_page(GFP_KERNEL)))
+ return -ENOMEM;
+
+ length = security_getprocattr(task,
+ (char*)file->f_dentry->d_name.name,
+ (void*)page, count);
+ if (length < 0) {
+ free_page(page);
+ return length;
+ }
+ /* Static 4kB (or whatever) block capacity */
+ if (*ppos >= length) {
+ free_page(page);
+ return 0;
+ }
+ if (count + *ppos > length)
+ count = length - *ppos;
+ end = count + *ppos;
+ if (copy_to_user(buf, (char *) page + *ppos, count))
+ count = -EFAULT;
+ else
+ *ppos = end;
+ free_page(page);
+ return count;
+}
+
+static ssize_t proc_pid_attr_write(struct file * file, const char * buf,
+ size_t count, loff_t *ppos)
+{
+ struct inode * inode = file->f_dentry->d_inode;
+ char *page;
+ ssize_t length;
+ struct task_struct *task = proc_task(inode);
+
+ if (count > PAGE_SIZE)
+ count = PAGE_SIZE;
+ if (*ppos != 0) {
+ /* No partial writes. */
+ return -EINVAL;
+ }
+ page = (char*)__get_free_page(GFP_USER);
+ if (!page)
+ return -ENOMEM;
+ length = -EFAULT;
+ if (copy_from_user(page, buf, count))
+ goto out;
+
+ length = security_setprocattr(task,
+ (char*)file->f_dentry->d_name.name,
+ (void*)page, count);
+out:
+ free_page((unsigned long) page);
+ return length;
+}
+
+static struct file_operations proc_pid_attr_operations = {
+ .read = proc_pid_attr_read,
+ .write = proc_pid_attr_write,
+};
+
+static struct file_operations proc_attr_operations;
+static struct inode_operations proc_attr_inode_operations;
+#endif
+
/* SMP-safe */
-static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
+static struct dentry *proc_pident_lookup(struct inode *dir,
+ struct dentry *dentry,
+ struct pid_entry *ents)
{
struct inode *inode;
int error;
@@ -990,7 +1116,10 @@
error = -ENOENT;
inode = NULL;
- for (p = base_stuff; p->name; p++) {
+ if (!pid_alive(task))
+ goto out;
+
+ for (p = ents; p->name; p++) {
if (p->len != dentry->d_name.len)
continue;
if (!memcmp(dentry->d_name.name, p->name, p->len))
@@ -1058,6 +1187,19 @@
case PROC_PID_MOUNTS:
inode->i_fop = &proc_mounts_operations;
break;
+#ifdef CONFIG_SECURITY
+ case PROC_PID_ATTR:
+ inode->i_nlink = 2;
+ inode->i_op = &proc_attr_inode_operations;
+ inode->i_fop = &proc_attr_operations;
+ break;
+ case PROC_PID_ATTR_CURRENT:
+ case PROC_PID_ATTR_PREV:
+ case PROC_PID_ATTR_EXEC:
+ case PROC_PID_ATTR_FSCREATE:
+ inode->i_fop = &proc_pid_attr_operations;
+ break;
+#endif
#ifdef CONFIG_KALLSYMS
case PROC_PID_WCHAN:
inode->i_fop = &proc_info_file_operations;
@@ -1071,14 +1213,16 @@
}
dentry->d_op = &pid_dentry_operations;
d_add(dentry, inode);
- if (!proc_task(dentry->d_inode)->pid)
- d_drop(dentry);
return NULL;
out:
return ERR_PTR(error);
}
+static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry){
+ return proc_pident_lookup(dir, dentry, base_stuff);
+}
+
static struct file_operations proc_base_operations = {
.read = generic_read_dir,
.readdir = proc_base_readdir,
@@ -1088,6 +1232,28 @@
.lookup = proc_base_lookup,
};
+#ifdef CONFIG_SECURITY
+static int proc_attr_readdir(struct file * filp,
+ void * dirent, filldir_t filldir)
+{
+ return proc_pident_readdir(filp,dirent,filldir,
+ attr_stuff,ARRAY_SIZE(attr_stuff));
+}
+
+static struct file_operations proc_attr_operations = {
+ .read = generic_read_dir,
+ .readdir = proc_attr_readdir,
+};
+
+static struct dentry *proc_attr_lookup(struct inode *dir, struct dentry *dentry){
+ return proc_pident_lookup(dir, dentry, attr_stuff);
+}
+
+static struct inode_operations proc_attr_inode_operations = {
+ .lookup = proc_attr_lookup,
+};
+#endif
+
/*
* /proc/self:
*/
@@ -1110,6 +1276,55 @@
.follow_link = proc_self_follow_link,
};
+/**
+ * proc_pid_unhash - Unhash /proc/<pid> entry from the dcache.
+ * @p: task that should be flushed.
+ *
+ * Drops the /proc/<pid> dcache entry from the hash chains.
+ *
+ * Dropping /proc/<pid> entries and detach_pid must be synchroneous,
+ * otherwise e.g. /proc/<pid>/exe might point to the wrong executable,
+ * if the pid value is immediately reused. This is enforced by
+ * - caller must acquire spin_lock(p->proc_lock)
+ * - must be called before detach_pid()
+ * - proc_pid_lookup acquires proc_lock, and checks that
+ * the target is not dead by looking at the attach count
+ * of PIDTYPE_PID.
+ */
+
+struct dentry *proc_pid_unhash(struct task_struct *p)
+{
+ struct dentry *proc_dentry;
+
+ proc_dentry = p->proc_dentry;
+ if (proc_dentry != NULL) {
+
+ spin_lock(&dcache_lock);
+ if (!d_unhashed(proc_dentry)) {
+ dget_locked(proc_dentry);
+ __d_drop(proc_dentry);
+ } else
+ proc_dentry = NULL;
+ spin_unlock(&dcache_lock);
+ }
+ return proc_dentry;
+}
+
+/**
+ * proc_pid_flush - recover memory used by stale /proc/<pid>/x entries
+ * @proc_entry: directoy to prune.
+ *
+ * Shrink the /proc directory that was used by the just killed thread.
+ */
+
+void proc_pid_flush(struct dentry *proc_dentry)
+{
+ if(proc_dentry != NULL) {
+ shrink_dcache_parent(proc_dentry);
+ dput(proc_dentry);
+ }
+}
+
/* SMP-safe */
struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry)
{
@@ -1158,12 +1373,12 @@
inode->i_flags|=S_IMMUTABLE;
dentry->d_op = &pid_base_dentry_operations;
+
+ spin_lock(&task->proc_lock);
+ task->proc_dentry = dentry;
d_add(dentry, inode);
- read_lock(&tasklist_lock);
- proc_task(dentry->d_inode)->proc_dentry = dentry;
- read_unlock(&tasklist_lock);
- if (!proc_task(dentry->d_inode)->pid)
- d_drop(dentry);
+ spin_unlock(&task->proc_lock);
+
return NULL;
out:
return ERR_PTR(-ENOENT);
@@ -1186,7 +1401,7 @@
read_lock(&tasklist_lock);
for_each_process(p) {
int pid = p->pid;
- if (!pid)
+ if (!pid_alive(p))
continue;
if (--index >= 0)
continue;
diff -Nru a/fs/select.c b/fs/select.c
--- a/fs/select.c Thu Jun 19 00:45:34 2003
+++ b/fs/select.c Thu Jun 19 00:45:34 2003
@@ -194,6 +194,7 @@
retval = 0;
for (;;) {
unsigned long *rinp, *routp, *rexp, *inp, *outp, *exp;
+
set_current_state(TASK_INTERRUPTIBLE);
inp = fds->in; outp = fds->out; exp = fds->ex;
@@ -238,9 +239,12 @@
}
}
}
- if (res_in) *rinp = res_in;
- if (res_out) *routp = res_out;
- if (res_ex) *rexp = res_ex;
+ if (res_in)
+ *rinp = res_in;
+ if (res_out)
+ *routp = res_out;
+ if (res_ex)
+ *rexp = res_ex;
}
wait = NULL;
if (retval || !__timeout || signal_pending(current))
diff -Nru a/include/asm-alpha/unistd.h b/include/asm-alpha/unistd.h
--- a/include/asm-alpha/unistd.h Thu Jun 19 00:45:34 2003
+++ b/include/asm-alpha/unistd.h Thu Jun 19 00:45:34 2003
@@ -616,6 +616,8 @@
#endif /* __KERNEL_SYSCALLS__ */
+#ifdef __KERNEL__
+
/*
* "Conditional" syscalls
*
@@ -628,4 +630,25 @@
*/
#define cond_syscall(x) asmlinkage long x() __attribute__((weak,alias("sys_ni_syscall")));
+/*
+ * System call handlers that, upon successful completion, need to return a negative value
+ * should call force_successful_syscall_return() right before returning. On architectures
+ * where the syscall convention provides for a separate error flag (e.g., alpha, ia64,
+ * ppc{,64}, sparc{,64}, possibly others), this macro can be used to ensure that the error
+ * flag will not get set. On architectures which do not support a separate error flag,
+ * the macro is a no-op and the spurious error condition needs to be filtered out by some
+ * other means (e.g., in user-level, by passing an extra argument to the syscall handler,
+ * or something along those lines).
+ *
+ * On alpha, we can clear the user's pt_regs->r0 to force a successful syscall.
+ *
+ * XXX TODO: if kernel-only threads do not have a dummy pt_regs structure at the top
+ * of the stack, this would cause kernel stack corruption. Either check
+ * first that we're not dealing with a kernel thread or change the kernel
+ * stacks to allocate a dummy pt_regs structure.
+ */
+#define alpha_task_regs(task) ((struct pt_regs *) ((long) task->thread_info + PAGE_SIZE) - 1)
+#define force_successful_syscall_return() (alpha_task_regs(current)->r0 = 0)
+
+#endif /* __KERNEL__ */
#endif /* _ALPHA_UNISTD_H */
diff -Nru a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
--- a/include/asm-i386/unistd.h Thu Jun 19 00:45:34 2003
+++ b/include/asm-i386/unistd.h Thu Jun 19 00:45:34 2003
@@ -393,29 +393,14 @@
#endif
-#ifdef __KERNEL__
-
/*
* "Conditional" syscalls
*
* What we want is __attribute__((weak,alias("sys_ni_syscall"))),
* but it doesn't work on all toolchains, so we just do it by hand
*/
+#ifndef cond_syscall
#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
+#endif
-/*
- * System call handlers that, upon successful completion, need to return a negative value
- * should call force_successful_syscall_return() right before returning. On architectures
- * where the syscall convention provides for a separate error flag (e.g., alpha, ia64,
- * ppc{,64}, sparc{,64}, possibly others), this macro can be used to ensure that the error
- * flag will not get set. On architectures which do not support a separate error flag,
- * the macro is a no-op and the spurious error condition needs to be filtered out by some
- * other means (e.g., in user-level, by passing an extra argument to the syscall handler,
- * or something along those lines).
- *
- * On x86, this is a no-op.
- */
-#define force_successful_syscall_return()
-
-#endif /* __KERNEL__ */
#endif /* _ASM_I386_UNISTD_H_ */
diff -Nru a/include/asm-ppc64/mmzone.h b/include/asm-ppc64/mmzone.h
--- a/include/asm-ppc64/mmzone.h Thu Jun 19 00:45:34 2003
+++ b/include/asm-ppc64/mmzone.h Thu Jun 19 00:45:34 2003
@@ -18,9 +18,10 @@
* Following are specific to this numa platform.
*/
-extern int numa_node_exists[];
extern int numa_cpu_lookup_table[];
extern int numa_memory_lookup_table[];
+extern unsigned long numa_cpumask_lookup_table[];
+extern int nr_cpus_in_node[];
#define MAX_MEMORY (1UL << 41)
/* 256MB regions */
diff -Nru a/include/asm-ppc64/module.h b/include/asm-ppc64/module.h
--- a/include/asm-ppc64/module.h Thu Jun 19 00:45:34 2003
+++ b/include/asm-ppc64/module.h Thu Jun 19 00:45:34 2003
@@ -1,6 +1,9 @@
#ifndef _ASM_PPC64_MODULE_H
#define _ASM_PPC64_MODULE_H
+#include <linux/list.h>
+#include <asm/bug.h>
+
struct mod_arch_specific
{
/* Index of stubs section within module. */
@@ -8,7 +11,14 @@
/* What section is the TOC? */
unsigned int toc_section;
+
+ /* List of BUG addresses, source line numbers and filenames */
+ struct list_head bug_list;
+ struct bug_entry *bug_table;
+ unsigned int num_bugs;
};
+
+extern struct bug_entry *module_find_bug(unsigned long bugaddr);
#define Elf_Shdr Elf64_Shdr
#define Elf_Sym Elf64_Sym
diff -Nru a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h
--- a/include/asm-ppc64/processor.h Thu Jun 19 00:45:34 2003
+++ b/include/asm-ppc64/processor.h Thu Jun 19 00:45:34 2003
@@ -469,8 +469,6 @@
#define IOCR_SPC 0x00000001
-/* Processor Version Register */
-
/* Processor Version Register (PVR) field extraction */
#define PVR_VER(pvr) (((pvr) >> 16) & 0xFFFF) /* Version field */
@@ -595,6 +593,8 @@
asm volatile("mfasr %0" : "=r" (rval)); rval;})
#ifndef __ASSEMBLY__
+extern unsigned long *_get_SP(void);
+
extern int have_of;
struct task_struct;
@@ -654,8 +654,10 @@
struct pt_regs *regs; /* Pointer to saved register state */
mm_segment_t fs; /* for get_fs() validation */
double fpr[32]; /* Complete floating point set */
- unsigned long fpscr; /* Floating point status */
- unsigned int fpexc_mode; /* Floating-point exception mode */
+ unsigned long fpscr; /* Floating point status (plus pad) */
+ unsigned long fpexc_mode; /* Floating-point exception mode */
+ unsigned long saved_msr; /* Save MSR across signal handlers */
+ unsigned long saved_softe; /* Ditto for Soft Enable/Disable */
};
#define INIT_SP (sizeof(init_stack) + (unsigned long) &init_stack)
@@ -702,7 +704,7 @@
return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8);
}
-static inline unsigned int __pack_fe01(unsigned int fpmode)
+static inline unsigned long __pack_fe01(unsigned int fpmode)
{
return ((fpmode << 10) & MSR_FE0) | ((fpmode << 8) & MSR_FE1);
}
@@ -728,17 +730,14 @@
#define spin_lock_prefetch(x) prefetchw(x)
-#define cpu_has_largepage() (processor_type() == PV_POWER4 || \
- processor_type() == PV_POWER4p)
-
-#define cpu_has_slb() (processor_type() == PV_POWER4 || \
- processor_type() == PV_POWER4p)
+/* XXX we have to call HV to set when in LPAR */
+#define cpu_has_dabr() (1)
-#define cpu_has_tlbiel() (processor_type() == PV_POWER4 || \
- processor_type() == PV_POWER4p)
+#define cpu_has_iabr() (processor_type() != PV_POWER4 && \
+ processor_type() != PV_POWER4p)
-#define cpu_has_noexecute() (processor_type() == PV_POWER4 || \
- processor_type() == PV_POWER4p)
+#define cpu_alignexc_sets_dsisr() (processor_type() != PV_POWER4 && \
+ processor_type() != PV_POWER4p)
#endif /* ASSEMBLY */
diff -Nru a/include/asm-ppc64/topology.h b/include/asm-ppc64/topology.h
--- a/include/asm-ppc64/topology.h Thu Jun 19 00:45:34 2003
+++ b/include/asm-ppc64/topology.h Thu Jun 19 00:45:34 2003
@@ -20,32 +20,25 @@
return node;
}
-static inline int node_to_first_cpu(int node)
-{
- int cpu;
+#define memblk_to_node(memblk) (memblk)
- for(cpu = 0; cpu < NR_CPUS; cpu++)
- if (numa_cpu_lookup_table[cpu] == node)
- return cpu;
+#define parent_node(node) (node)
- BUG(); /* couldn't find a cpu on given node */
- return -1;
+static inline unsigned long node_to_cpumask(int node)
+{
+ return numa_cpumask_lookup_table[node];
}
-static inline unsigned long node_to_cpumask(int node)
+static inline int node_to_first_cpu(int node)
{
- int cpu;
- unsigned long mask = 0UL;
+ return __ffs(node_to_cpumask(node));
+}
- if (sizeof(unsigned long) * 8 < NR_CPUS)
- BUG();
+#define node_to_memblk(node) (node)
- for(cpu = 0; cpu < NR_CPUS; cpu++)
- if (numa_cpu_lookup_table[cpu] == node)
- mask |= 1UL << cpu;
+#define pcibus_to_cpumask(bus) (cpu_online_map)
- return mask;
-}
+#define nr_cpus_node(node) (nr_cpus_in_node[node])
/* Cross-node load balancing interval. */
#define NODE_BALANCE_RATE 10
diff -Nru a/include/asm-ppc64/unistd.h b/include/asm-ppc64/unistd.h
--- a/include/asm-ppc64/unistd.h Thu Jun 19 00:45:34 2003
+++ b/include/asm-ppc64/unistd.h Thu Jun 19 00:45:34 2003
@@ -260,7 +260,7 @@
#define __NR_clock_getres 247
#define __NR_clock_nanosleep 248
-#define __NR_syscalls 239
+#define __NR_syscalls 249
#ifdef __KERNEL__
#define NR_syscalls __NR_syscalls
#endif
@@ -390,6 +390,8 @@
#endif /* __KERNEL_SYSCALLS__ */
+#ifdef __KERNEL__
+
/*
* "Conditional" syscalls
*
@@ -397,6 +399,23 @@
* but it doesn't work on all toolchains, so we just do it by hand
*/
#define cond_syscall(x) asm(".weak\t." #x "\n\t.set\t." #x ",.sys_ni_syscall");
+
+/*
+ * System call handlers that, upon successful completion, need to return a negative value
+ * should call force_successful_syscall_return() right before returning. On architectures
+ * where the syscall convention provides for a separate error flag (e.g., alpha, ia64,
+ * ppc{,64}, sparc{,64}, possibly others), this macro can be used to ensure that the error
+ * flag will not get set. On architectures which do not support a separate error flag,
+ * the macro is a no-op and the spurious error condition needs to be filtered out by some
+ * other means (e.g., in user-level, by passing an extra argument to the syscall handler,
+ * or something along those lines).
+ *
+ * On PPC64, the syscall error flag is returned via the SO bit in CR, but for now there is
+ * no way to force that bit to zero, so we do nothing here.
+ */
+#define force_successful_syscall_return()
+
+#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
diff -Nru a/include/linux/highmem.h b/include/linux/highmem.h
--- a/include/linux/highmem.h Thu Jun 19 00:45:34 2003
+++ b/include/linux/highmem.h Thu Jun 19 00:45:34 2003
@@ -3,6 +3,8 @@
#include <linux/config.h>
#include <linux/fs.h>
+#include <linux/mm.h>
+
#include <asm/cacheflush.h>
#ifdef CONFIG_HIGHMEM
diff -Nru a/include/linux/irq.h b/include/linux/irq.h
--- a/include/linux/irq.h Thu Jun 19 00:45:34 2003
+++ b/include/linux/irq.h Thu Jun 19 00:45:34 2003
@@ -56,7 +56,7 @@
*
* Pad this out to 32 bytes for cache and indexing reasons.
*/
-typedef struct {
+typedef struct irq_desc {
unsigned int status; /* IRQ status */
hw_irq_controller *handler;
struct irqaction *action; /* IRQ action list */
@@ -65,8 +65,6 @@
unsigned int irqs_unhandled;
spinlock_t lock;
} ____cacheline_aligned irq_desc_t;
-
-extern irq_desc_t irq_desc [NR_IRQS];
#include <asm/hw_irq.h> /* the arch dependent stuff */
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h Thu Jun 19 00:45:34 2003
+++ b/include/linux/pci_ids.h Thu Jun 19 00:45:34 2003
@@ -602,6 +602,8 @@
#define PCI_DEVICE_ID_HP_DIVA_TOSCA1 0x1049
#define PCI_DEVICE_ID_HP_DIVA_TOSCA2 0x104A
#define PCI_DEVICE_ID_HP_DIVA_MAESTRO 0x104B
+#define PCI_DEVICE_ID_HP_REO_SBA 0x10f0
+#define PCI_DEVICE_ID_HP_REO_IOC 0x10f1
#define PCI_DEVICE_ID_HP_VISUALIZE_FXE 0x108b
#define PCI_DEVICE_ID_HP_DIVA_HALFDOME 0x1223
#define PCI_DEVICE_ID_HP_DIVA_KEYSTONE 0x1226
diff -Nru a/include/linux/sched.h b/include/linux/sched.h
--- a/include/linux/sched.h Thu Jun 19 00:45:34 2003
+++ b/include/linux/sched.h Thu Jun 19 00:45:34 2003
@@ -148,10 +148,15 @@
extern void init_idle(task_t *idle, int cpu);
extern void show_state(void);
-extern void show_trace(unsigned long *stack);
-extern void show_stack(unsigned long *stack);
extern void show_regs(struct pt_regs *);
+/*
+ * TASK is a pointer to the task whose backtrace we want to see (or NULL for current
+ * task), SP is the stack pointer of the first frame that should be shown in the back
+ * trace (or NULL if the entire call-chain of the task should be shown).
+ */
+extern void show_stack(struct task_struct *task, unsigned long *sp);
+
void io_schedule(void);
long io_schedule_timeout(long timeout);
@@ -506,14 +511,14 @@
#ifndef INIT_THREAD_SIZE
# define INIT_THREAD_SIZE 2048*sizeof(long)
-#endif
-
union thread_union {
struct thread_info thread_info;
unsigned long stack[INIT_THREAD_SIZE/sizeof(long)];
};
extern union thread_union init_thread_union;
+#endif
+
extern struct task_struct init_task;
extern struct mm_struct init_mm;
diff -Nru a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
--- a/include/linux/sunrpc/svc.h Thu Jun 19 00:45:34 2003
+++ b/include/linux/sunrpc/svc.h Thu Jun 19 00:45:34 2003
@@ -176,8 +176,10 @@
{
if (rqstp->rq_arghi <= rqstp->rq_argused)
return -ENOMEM;
- rqstp->rq_respages[rqstp->rq_resused++] =
- rqstp->rq_argpages[--rqstp->rq_arghi];
+ rqstp->rq_arghi--;
+ rqstp->rq_respages[rqstp->rq_resused] =
+ rqstp->rq_argpages[rqstp->rq_arghi];
+ rqstp->rq_resused++;
return 0;
}
diff -Nru a/include/linux/sysctl.h b/include/linux/sysctl.h
--- a/include/linux/sysctl.h Thu Jun 19 00:45:34 2003
+++ b/include/linux/sysctl.h Thu Jun 19 00:45:34 2003
@@ -130,6 +130,7 @@
KERN_PIDMAX=55, /* int: PID # limit */
KERN_CORE_PATTERN=56, /* string: pattern for core-file names */
KERN_PANIC_ON_OOPS=57, /* int: whether we will panic on an oops */
+ KERN_CACHEDECAYTICKS=58, /* ulong: value for cache_decay_ticks (EXPERIMENTAL!) */
};
diff -Nru a/include/linux/time.h b/include/linux/time.h
--- a/include/linux/time.h Thu Jun 19 00:45:34 2003
+++ b/include/linux/time.h Thu Jun 19 00:45:34 2003
@@ -162,7 +162,7 @@
extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
extern void clock_was_set(void); // call when ever the clock is set
extern long do_nanosleep(struct timespec *t);
-extern long do_utimes(char * filename, struct timeval * times);
+extern long do_utimes(char __user * filename, struct timeval * times);
#endif
#define FD_SETSIZE __FD_SETSIZE
diff -Nru a/kernel/fork.c b/kernel/fork.c
--- a/kernel/fork.c Thu Jun 19 00:45:34 2003
+++ b/kernel/fork.c Thu Jun 19 00:45:34 2003
@@ -888,11 +888,15 @@
if (clone_flags & CLONE_CHILD_SETTID)
p->set_child_tid = child_tidptr;
+ else
+ p->set_child_tid = NULL;
/*
* Clear TID on mm_release()?
*/
if (clone_flags & CLONE_CHILD_CLEARTID)
p->clear_child_tid = child_tidptr;
+ else
+ p->clear_child_tid = NULL;
/*
* Syscall tracing should be turned off in the child regardless
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
--- a/kernel/ksyms.c Thu Jun 19 00:45:34 2003
+++ b/kernel/ksyms.c Thu Jun 19 00:45:34 2003
@@ -592,7 +592,9 @@
/* init task, for moving kthread roots - ought to export a function ?? */
EXPORT_SYMBOL(init_task);
+#ifndef CONFIG_IA64
EXPORT_SYMBOL(init_thread_union);
+#endif
EXPORT_SYMBOL(tasklist_lock);
EXPORT_SYMBOL(find_task_by_pid);
diff -Nru a/kernel/posix-timers.c b/kernel/posix-timers.c
--- a/kernel/posix-timers.c Thu Jun 19 00:45:34 2003
+++ b/kernel/posix-timers.c Thu Jun 19 00:45:34 2003
@@ -33,12 +33,7 @@
result; })
#endif
-#define CLOCK_REALTIME_RES TICK_NSEC(TICK_USEC) // In nano seconds.
-static inline u64 mpy_l_X_l_ll(unsigned long mpy1,unsigned long mpy2)
-{
- return (u64)mpy1 * mpy2;
-}
/*
* Management arrays for POSIX timers. Timers are kept in slab memory
* Timer ids are allocated by an external routine that keeps track of the
@@ -180,8 +175,8 @@
*/
static __init int init_posix_timers(void)
{
- struct k_clock clock_realtime = {.res = CLOCK_REALTIME_RES };
- struct k_clock clock_monotonic = {.res = CLOCK_REALTIME_RES,
+ struct k_clock clock_realtime = {.res = NSEC_PER_SEC / HZ };
+ struct k_clock clock_monotonic = {.res = NSEC_PER_SEC / HZ,
.clock_get = do_posix_clock_monotonic_gettime,
.clock_set = do_posix_clock_monotonic_settime
};
@@ -209,14 +204,24 @@
}
/*
- * The scaling constants are defined in <linux/time.h>
- * The difference between there and here is that we do the
- * res rounding and compute a 64-bit result (well so does that
- * but it then throws away the high bits).
- */
- *jiff = (mpy_l_X_l_ll(sec, SEC_CONVERSION) +
- (mpy_l_X_l_ll(nsec, NSEC_CONVERSION) >>
- (NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC;
+ * A note on jiffy overflow: It is possible for the system to
+ * have been up long enough for the jiffies quanity to overflow.
+ * In order for correct timer evaluations we require that the
+ * specified time be somewhere between now and now + (max
+ * unsigned int/2). Times beyond this will be truncated back to
+ * this value. This is done in the absolute adjustment code,
+ * below. Here it is enough to just discard the high order
+ * bits.
+ */
+ *jiff = (s64)sec * HZ;
+ /*
+ * Do the res thing. (Don't forget the add in the declaration of nsec)
+ */
+ nsec -= nsec % res;
+ /*
+ * Split to jiffie and sub jiffie
+ */
+ *jiff += nsec / (NSEC_PER_SEC / HZ);
}
static void schedule_next_timer(struct k_itimer *timr)
@@ -1215,6 +1220,7 @@
finish_wait(&nanosleep_abs_wqueue, &abs_wqueue);
if (left > (s64)0) {
+ unsigned long rmd;
/*
* Always restart abs calls from scratch to pick up any
@@ -1223,10 +1229,9 @@
if (abs)
return -ERESTARTNOHAND;
- left *= TICK_NSEC(TICK_USEC);
- tsave->tv_sec = div_long_long_rem(left,
- NSEC_PER_SEC,
- &tsave->tv_nsec);
+ tsave->tv_sec = div_long_long_rem(left, HZ, &rmd);
+ tsave->tv_nsec = rmd * (NSEC_PER_SEC / HZ);
+
restart_block->fn = clock_nanosleep_restart;
restart_block->arg0 = which_clock;
restart_block->arg1 = (unsigned long)tsave;
diff -Nru a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c Thu Jun 19 00:45:34 2003
+++ b/kernel/sched.c Thu Jun 19 00:45:34 2003
@@ -2179,10 +2179,7 @@
else
printk(" (NOTLB)\n");
- {
- extern void show_trace_task(task_t *tsk);
- show_trace_task(p);
- }
+ show_stack(p, NULL);
}
void show_state(void)
diff -Nru a/kernel/sys.c b/kernel/sys.c
--- a/kernel/sys.c Thu Jun 19 00:45:34 2003
+++ b/kernel/sys.c Thu Jun 19 00:45:34 2003
@@ -1219,7 +1219,7 @@
? -EFAULT : 0;
}
-#if !defined(__ia64__) && !defined(CONFIG_V850)
+#if (!defined(__ia64__) && !defined(CONFIG_V850)) || defined(CONFIG_COMPAT)
/*
* Back compatibility for getrlimit. Needed for some apps.
diff -Nru a/mm/memory.c b/mm/memory.c
--- a/mm/memory.c Thu Jun 19 00:45:34 2003
+++ b/mm/memory.c Thu Jun 19 00:45:34 2003
@@ -114,8 +114,10 @@
}
pmd = pmd_offset(dir, 0);
pgd_clear(dir);
- for (j = 0; j < PTRS_PER_PMD ; j++)
+ for (j = 0; j < PTRS_PER_PMD ; j++) {
+ prefetchw(pmd + j + PREFETCH_STRIDE/sizeof(*pmd));
free_one_pmd(tlb, pmd+j);
+ }
pmd_free_tlb(tlb, pmd);
}